淺談Java中的LinkedHashSet哈希鏈表
HashSet哈希鏈表
Map、Set集合存放是無(wú)序的,然而LinkedHashSet和LinkedHashMap等集合卻有序
原因:LinkedHashSet與LinkedHashMap底層是通過(guò)雙向鏈表來(lái)實(shí)現(xiàn)排序的。
雙向鏈表里面的數(shù)據(jù)在邏輯上的存儲(chǔ)是連續(xù)的,連續(xù)自然也就有順序。
有序的原因關(guān)鍵在LinkedHashMap的Node 節(jié)點(diǎn)上。
LinkedHashMap 繼承自HashMap 并且實(shí)現(xiàn)了Map接口。
源碼如下:
/**
HashMap.Node subclass for normal LinkedHashMap entries.
*/
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}可以看到LinkedHashMap.Entry 繼承自HashMap.Node 除了Node 本身有的幾個(gè)屬性外,額外增加了before after 用于指向前一個(gè)Entry 后一個(gè)Entry。
也就是說(shuō),元素之間維持著一條總的鏈表數(shù)據(jù)結(jié)構(gòu)。正式因?yàn)檫@個(gè)鏈表才保證了LinkedHashMap的有序性。
LinkedHashSet集合也是根據(jù)元素hashCode值來(lái)決定元素存儲(chǔ)位置,但它同時(shí)使用鏈表維護(hù)元素的次序,這樣使得元素看起來(lái)是以插入的順序保存的。
也就是說(shuō),當(dāng)遍歷LinkedHashSet集合里元素時(shí),HashSet將會(huì)按元素的添加順序來(lái)訪(fǎng)問(wèn)集合里的元素,因此LinkedHashSet可以保證元素按插入順序輸出。
而Set對(duì)每個(gè)對(duì)象只接受一次,里面的值不允許重復(fù),是無(wú)序的數(shù)據(jù)結(jié)構(gòu);
LinkeHashSet是set集合的一個(gè)實(shí)現(xiàn),具有set集合不重復(fù)的特點(diǎn),同時(shí)具有可預(yù)測(cè)的迭代順序,即輸入順序。
這種雙鏈表的結(jié)構(gòu)一條用于儲(chǔ)存元素,一條用于記錄順序。
而Map Set集合內(nèi)是單鏈表或稀疏數(shù)組,各元素之間并沒(méi)有維持一條總的鏈表結(jié)構(gòu),所以Map和Set是無(wú)序的
LinkedHashSet的4種構(gòu)造函數(shù):
- 第一種構(gòu)造函數(shù)初始化一個(gè)空的LinkedHashSet: LinkedHashSet( );
- 第二種構(gòu)造函數(shù)使用Collection元素集初始化LinkedHashSet: LinkedHashSet(Collection c);
- 第三種構(gòu)造函數(shù)用給定的容量初始化LinkedHashSet: LinkedHashSet(int capacity);
- 第四種構(gòu)造函數(shù)通過(guò)傳入的容量和填充比初始化LinkedHashSet: LinkedHashSet(int capacity, float fillRatio);

運(yùn)行結(jié)果:

這兩斷代碼我們可以得出:LinkedHashSet 底層采用雙向鏈表實(shí)現(xiàn),可以保證元素的插入順序,又因?yàn)槭荋ashSet的子類(lèi),所以插入的元素不能重復(fù)。
到此這篇關(guān)于淺談Java中的LinkedHashSet哈希鏈表的文章就介紹到這了,更多相關(guān)Java的LinkedHashSet內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JVM內(nèi)存結(jié)構(gòu)相關(guān)知識(shí)解析
這篇文章主要介紹了JVM內(nèi)存結(jié)構(gòu)相關(guān)知識(shí)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
淺談一下Java中的悲觀(guān)鎖和樂(lè)觀(guān)鎖
這篇文章主要介紹了一下Java中的悲觀(guān)鎖和樂(lè)觀(guān)鎖,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
Spring復(fù)雜對(duì)象創(chuàng)建的方式小結(jié)
這篇文章主要介紹了Spring復(fù)雜對(duì)象創(chuàng)建的三種方式,現(xiàn)在使用Spring如何創(chuàng)建這種類(lèi)型的對(duì)象?Spring中提供了三種方法來(lái)創(chuàng)建復(fù)雜對(duì)象,需要的朋友可以參考下2022-01-01
SpringBoot項(xiàng)目中使用Swagger2及注解解釋的詳細(xì)教程
Swagger2是一個(gè)開(kāi)源項(xiàng)目,用于為RESTful Web服務(wù)生成REST API文檔,下面這篇文章主要給大家介紹了關(guān)于SpringBoot項(xiàng)目中使用Swagger2及注解解釋的詳細(xì)教程,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04
Java適配器模式之如何靈活應(yīng)對(duì)不匹配的接口
本文介紹了Java中的適配器模式,包括對(duì)象適配器模式和接口適配器模式,適配器模式通過(guò)將一個(gè)類(lèi)的接口轉(zhuǎn)換成客戶(hù)期望的另一個(gè)接口,解決了不同接口之間的不兼容問(wèn)題,它提高了系統(tǒng)的靈活性、復(fù)用性和解耦性,需要的朋友可以參考下2024-10-10
從零搭建Spring Boot腳手架整合OSS作為文件服務(wù)器的詳細(xì)教程
這篇文章主要介紹了從零搭建Spring Boot腳手架整合OSS作為文件服務(wù)器的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
Java多線(xiàn)程CyclicBarrier的實(shí)現(xiàn)代碼
CyclicBarrier可以使一定數(shù)量的線(xiàn)程反復(fù)地在柵欄位置處匯集,本文通過(guò)實(shí)例代碼介紹下Java多線(xiàn)程CyclicBarrier的相關(guān)知識(shí),感興趣的朋友一起看看吧2022-02-02
Spring中的ClassPathXmlApplicationContext源碼詳解
這篇文章主要介紹了Spring中的ClassPathXmlApplicationContext源碼詳解,ApplicationContext的主要實(shí)現(xiàn)類(lèi)是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默認(rèn)從類(lèi)路徑加載配置文件,后者默認(rèn)從文件系統(tǒng)中裝載配置文件,需要的朋友可以參考下2023-12-12

