因?yàn)槭荋ashSet的子類,所以也是保證元素唯一的,與HashSet的原理一樣,需要的朋友可以參考下" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Java的LinkedHashSet源碼

 更新時(shí)間:2023年09月05日 10:50:59   作者:小成同學(xué)_  
這篇文章主要介紹了淺談Java的LinkedHashSet源碼,底層是鏈表實(shí)現(xiàn)的,是set集合中唯一一個(gè)能保證怎么存就怎么取的集合對(duì)象
因?yàn)槭荋ashSet的子類,所以也是保證元素唯一的,與HashSet的原理一樣,需要的朋友可以參考下

LinkedHashSet

問題

(1)LinkedHashSet 的底層使用什么存儲(chǔ)元素?

(2)LinkedHashSet 與 HashSet 有什么不同?

(3)LinkedHashSet 是有序的嗎?

(4)LinkedHashSet 支持按元素訪問順序排序嗎?

LinkedHashSet的概述和使用

A:LinkedHashSet的特點(diǎn)

LinkedHashSet

底層是鏈表實(shí)現(xiàn)的,是set集合中唯一一個(gè)能保證怎么存就怎么取的集合對(duì)象

因?yàn)槭荋ashSet的子類,所以也是保證元素唯一的,與HashSet的原理一樣

B:案例演示

LinkedHashSet的特點(diǎn)

可以保證怎么存就怎么取

package com.heima.set;
import java.util.LinkedHashSet;
public class Demo02_LinkedHashSet {
	public static void main(String[] args) {
		LinkedHashSet<String> lhs = new LinkedHashSet<>();
		lhs.add("a");
		lhs.add("a");
		lhs.add("a");
		lhs.add("a");
		lhs.add("b");
		lhs.add("c");
		lhs.add("d");
		System.out.println(lhs);
	}
}

上一節(jié)我們說 HashSet 中的元素是無序的,那么有沒有什么辦法保證 Set 中的元素是有序的呢?

答案是當(dāng)然可以。

我們今天的主角 LinkedHashSet 就有這個(gè)功能,它是怎么實(shí)現(xiàn)有序的呢?讓我們來一起學(xué)習(xí)吧。

如果你已看過前面關(guān)于 HashSet 和 HashMap,一定能夠想到本文將要講解的 LinkedHashSet 和 LinkedHashMap 其實(shí)也是一回事,前者僅僅是對(duì)后者做了一層包裝,也就是說 LinkedHashSet 里面有一個(gè) LinkedHashMap(適配器模式)。

LinkedHashSet 的本質(zhì)就是 LinkedHashMap。

繼承體系

image-20221203211217024

源碼解析

LinkedHashSet 繼承了 HashSet,其增刪改查等方法使用的都是 HashSet 的方法,我們直接看它的全部源碼。

package java.util;
// LinkedHashSet繼承自HashSet
public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {
    private static final long serialVersionUID = -2851667679971038690L;
    // 傳入容量和裝載因子
    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }
    // 只傳入容量,裝載因子默認(rèn)為0.75
    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }
    // 使用默認(rèn)容量16,默認(rèn)裝載因子0.75
    public LinkedHashSet() {
        super(16, .75f, true);
    }
    // 將集合c中的所有元素添加到LinkedHashSet中
    // 好奇怪,這里計(jì)算容量的方式又變了
    // HashSet中使用的是Math.max((int) (c.size()/.75f) + 1, 16)
    // 這一點(diǎn)有點(diǎn)不得其解,是作者偷懶?
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }
    // 可分割的迭代器,主要用于多線程并行迭代處理時(shí)使用
    @Override
    public Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
    }
}

完了,結(jié)束了,就這么多,這是全部源碼了,真的。

可以看到,LinkedHashSet 中一共提供了 5 個(gè)方法,其中 4 個(gè)是構(gòu)造方法,還有一個(gè)是迭代器。

4 個(gè)構(gòu)造方法都是調(diào)用父類的 super(initialCapacity, loadFactor, true); 這個(gè)方法。

這個(gè)方法長(zhǎng)什么樣呢?

還記得我們上一節(jié)說過一個(gè)不是 public 的構(gòu)造方法嗎?就是它。

    // HashSet的構(gòu)造方法
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }
					   ||
				  	   \/
	// 上面的構(gòu)造器調(diào)用的是LinkedHashMap的這個(gè)構(gòu)造器,其accessOrder是固定的為false,即不能實(shí)現(xiàn)LRU,鏈表只能按照元素的添加順序進(jìn)行排序。
    public LinkedHashMap(int initialCapacity, float loadFactor) {
        // 再調(diào)用HashMap的構(gòu)造器
        super(initialCapacity, loadFactor);
        // accessOrder固定為false,不能為其賦值,即不支持LRU。
        accessOrder = false;
    }

如上所示,這個(gè)構(gòu)造方法里面使用了 LinkedHashMap 來初始化 HashSet 中的 map。

現(xiàn)在這個(gè)邏輯應(yīng)該很清晰了,LinkedHashSet 繼承自 HashSet,它的添加、刪除、查詢等方法都是直接用的 HashSet 的,唯一的不同就是它使用 LinkedHashMap 存儲(chǔ)元素。

上一篇我們學(xué)習(xí)了 LinkedHashMap,此時(shí)我們會(huì)想到一個(gè)問題,既然 LinkedHashSet 是基于 LinkedHashMap 實(shí)現(xiàn)的,那它可以實(shí)現(xiàn) LRU 嗎?

答案是 不可以。

因?yàn)槲覀兛吹?,LinkedHashSet 所有的構(gòu)造方法都是調(diào)用 HashSet 的同一個(gè)構(gòu)造方法,而 HashSet 中初始化 map 的構(gòu)造方法,默認(rèn)把 accessOrder 設(shè)置為 false 了。

所以,LinkedHashSet 是不支持按訪問順序?qū)υ嘏判虻模?strong>無法實(shí)現(xiàn) LRU,只能按插入順序排序。

那么,開篇那幾個(gè)問題是否能回答了呢?

總結(jié)

(1)LinkedHashSet 的底層使用 LinkedHashMap 存儲(chǔ)元素。

(2)LinkedHashSet 是有序的,它是按照插入的順序排序的 (不支持 LRU)

到此這篇關(guān)于淺談Java的LinkedHashSet源碼的文章就介紹到這了,更多相關(guān)Java的LinkedHashSet內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring mvc 讀取xml文件數(shù)據(jù)庫配置參數(shù)的方法

    spring mvc 讀取xml文件數(shù)據(jù)庫配置參數(shù)的方法

    下面小編就為大家?guī)硪黄猻pring mvc 讀取xml文件數(shù)據(jù)庫配置參數(shù)的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • java 中Comparable與Comparator詳解與比較

    java 中Comparable與Comparator詳解與比較

    這篇文章主要介紹了java 中Comparable與Comparator詳解與比較的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • 在Intellij Idea中使用jstl標(biāo)簽庫的方法

    在Intellij Idea中使用jstl標(biāo)簽庫的方法

    這篇文章主要介紹了在Intellij Idea中使用jstl標(biāo)簽庫的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • JAVA如何獲取客戶端IP地址和MAC地址

    JAVA如何獲取客戶端IP地址和MAC地址

    本篇文章主要介紹了JAVA如何獲取客戶端IP地址和MAC地址非常具有實(shí)用價(jià)值,這里整理了詳細(xì)的代碼,需要的朋友可以參考下
    2017-08-08
  • Springboot實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)流程詳解

    Springboot實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)流程詳解

    通過重寫SchedulingConfigurer方法實(shí)現(xiàn)對(duì)定時(shí)任務(wù)的操作,單次執(zhí)行、停止、啟動(dòng)三個(gè)主要的基本功能,動(dòng)態(tài)的從數(shù)據(jù)庫中獲取配置的定時(shí)任務(wù)cron信息,通過反射的方式靈活定位到具體的類與方法中
    2022-09-09
  • java socket大數(shù)據(jù)傳輸丟失問題及解決

    java socket大數(shù)據(jù)傳輸丟失問題及解決

    這篇文章主要介紹了java socket大數(shù)據(jù)傳輸丟失問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 使用Scala生成隨機(jī)數(shù)的方法示例

    使用Scala生成隨機(jī)數(shù)的方法示例

    這篇文章主要介紹了使用Scala生成隨機(jī)數(shù)的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Java匿名類和匿名函數(shù)的概念和寫法

    Java匿名類和匿名函數(shù)的概念和寫法

    匿名函數(shù)寫法和匿名類寫法的前提必須基于函數(shù)式接口匿名函數(shù)寫法和匿名類寫法其本質(zhì)是同一個(gè)東西,只是簡(jiǎn)化寫法不同使用Lambda表達(dá)式簡(jiǎn)寫匿名函數(shù)時(shí),可以同時(shí)省略實(shí)現(xiàn)類名、函數(shù)名,這篇文章主要介紹了Java匿名類和匿名函數(shù)的概念和寫法,需要的朋友可以參考下
    2023-06-06
  • 詳解Spring Boot Profiles 配置和使用

    詳解Spring Boot Profiles 配置和使用

    本篇文章主要介紹了詳解Spring Boot Profiles 配置和使用,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-06-06
  • Java上傳文件到服務(wù)器端的方法

    Java上傳文件到服務(wù)器端的方法

    這篇文章主要為大家詳細(xì)介紹了Java上傳文件到服務(wù)器端的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評(píng)論

沾化县| 尼玛县| 宁强县| 兴隆县| 铁岭市| 承德县| 于田县| 灵武市| 北流市| 县级市| 柳河县| 会东县| 桃源县| 金堂县| 永和县| 平邑县| 新安县| 会昌县| 香港 | 澄迈县| 高阳县| 延长县| 海林市| 乐都县| 张家川| 丰镇市| 西乌珠穆沁旗| 讷河市| 石阡县| 乌拉特前旗| 白银市| 察雅县| 新乡市| 赞皇县| 荆门市| 灵石县| 龙南县| 平原县| 怀安县| 贵定县| 新沂市|