因為是HashSet的子類,所以也是保證元素唯一的,與HashSet的原理一樣,需要的朋友可以參考下" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Java的LinkedHashSet源碼

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

LinkedHashSet

問題

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

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

(3)LinkedHashSet 是有序的嗎?

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

LinkedHashSet的概述和使用

A:LinkedHashSet的特點

LinkedHashSet

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

因為是HashSet的子類,所以也是保證元素唯一的,與HashSet的原理一樣

B:案例演示

LinkedHashSet的特點

可以保證怎么存就怎么取

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 就有這個功能,它是怎么實現(xiàn)有序的呢?讓我們來一起學(xué)習(xí)吧。

如果你已看過前面關(guān)于 HashSet 和 HashMap,一定能夠想到本文將要講解的 LinkedHashSet 和 LinkedHashMap 其實也是一回事,前者僅僅是對后者做了一層包裝,也就是說 LinkedHashSet 里面有一個 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中
    // 好奇怪,這里計算容量的方式又變了
    // HashSet中使用的是Math.max((int) (c.size()/.75f) + 1, 16)
    // 這一點有點不得其解,是作者偷懶?
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }
    // 可分割的迭代器,主要用于多線程并行迭代處理時使用
    @Override
    public Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
    }
}

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

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

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

這個方法長什么樣呢?

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

    // HashSet的構(gòu)造方法
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }
					   ||
				  	   \/
	// 上面的構(gòu)造器調(diào)用的是LinkedHashMap的這個構(gòu)造器,其accessOrder是固定的為false,即不能實現(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òu)造方法里面使用了 LinkedHashMap 來初始化 HashSet 中的 map。

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

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

答案是 不可以。

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

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

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

總結(jié)

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

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

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

相關(guān)文章

  • java實現(xiàn)多人聊天系統(tǒng)

    java實現(xiàn)多人聊天系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)多人聊天系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • 簡單了解Spring中的事務(wù)控制

    簡單了解Spring中的事務(wù)控制

    這篇文章主要介紹了簡單了解Spring中的事務(wù)控制,事務(wù)是一組操作的執(zhí)行單元,下面我們來簡單學(xué)習(xí)一下吧
    2019-05-05
  • Java數(shù)據(jù)結(jié)構(gòu)之實現(xiàn)跳表

    Java數(shù)據(jù)結(jié)構(gòu)之實現(xiàn)跳表

    今天帶大家來學(xué)習(xí)Java數(shù)據(jù)結(jié)構(gòu)的相關(guān)知識,文中對用Java實現(xiàn)跳表作了非常詳細(xì)的圖文解說及代碼示例,對正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • JAVA內(nèi)部類示例詳解及練習(xí)

    JAVA內(nèi)部類示例詳解及練習(xí)

    這篇文章主要為大家詳細(xì)介紹了Java的內(nèi)部類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • java不解壓直接讀取壓縮包中文件的實現(xiàn)方法

    java不解壓直接讀取壓縮包中文件的實現(xiàn)方法

    這篇文章主要介紹了java不解壓直接讀取壓縮包中文件的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • java實現(xiàn)學(xué)生成績檔案管理系統(tǒng)

    java實現(xiàn)學(xué)生成績檔案管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)學(xué)生成績檔案管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • java基本教程之線程休眠 java多線程教程

    java基本教程之線程休眠 java多線程教程

    本文對javaThread中sleep()方法進(jìn)行介紹,sleep() 的作用是讓當(dāng)前線程休眠,即當(dāng)前線程會從“運行狀態(tài)”進(jìn)入到“休眠(阻塞)狀態(tài)”,大家參考使用吧
    2014-01-01
  • Linux 下通過 java 命令啟動 jar 包常見方式小結(jié)

    Linux 下通過 java 命令啟動 jar 包常見方式小結(jié)

    這篇文章主要介紹了Linux 下通過 java 命令啟動 jar 包常見方式小結(jié),后臺啟動jar包命令大致有五種,每種方式結(jié)合代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2023-12-12
  • 詳解關(guān)于IntelliJ IDEA中Schedule for Addition 的問題

    詳解關(guān)于IntelliJ IDEA中Schedule for Addition 的問題

    本篇文章主要介紹了詳解關(guān)于 IntelliJ IDEA 中 Schedule for Addition 的問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • JavaEE中struts2實現(xiàn)文件上傳下載功能實例解析

    JavaEE中struts2實現(xiàn)文件上傳下載功能實例解析

    這篇文章主要為大家詳細(xì)介紹了JavaEE中struts2實現(xiàn)文件上傳下載功能實例,感興趣的小伙伴們可以參考一下
    2016-05-05

最新評論