Java中LinkedHashSet、LinkedHashMap源碼詳解
1.LinkedHashSet、LinkedHashMap總結(jié)
- LinkedHashSet底層實(shí)現(xiàn)為L(zhǎng)inkedHashMap
- 數(shù)據(jù)結(jié)構(gòu)為數(shù)組+雙鏈表/紅黑樹(shù)(當(dāng)數(shù)組長(zhǎng)度不小于64,鏈表長(zhǎng)度不小于8,該鏈表轉(zhuǎn)成樹(shù)結(jié)構(gòu))
- 線(xiàn)程不安全
- 根據(jù)插入順序進(jìn)行排序
備注:
紅黑樹(shù)(特殊的平衡二叉樹(shù))5大特性:
- 每個(gè)節(jié)點(diǎn)或者是黑色,或者是紅色。
- 根節(jié)點(diǎn)是黑色。
- 每個(gè)葉子節(jié)點(diǎn)(NIL)是黑色。 [注意:這里葉子節(jié)點(diǎn),是指為空(NIL或NULL)的葉子節(jié)點(diǎn)!]
- 如果一個(gè)節(jié)點(diǎn)是紅色的,則它的子節(jié)點(diǎn)必須是黑色的。
- 從一個(gè)節(jié)點(diǎn)到該節(jié)點(diǎn)的子孫節(jié)點(diǎn)的所有路徑上包含相同數(shù)目的黑節(jié)點(diǎn)。
2.分點(diǎn)詳解
2.1 LinkedHashSet
2.1.1 繼承實(shí)現(xiàn)情況
2.1.2 構(gòu)造方法
//1.無(wú)參構(gòu)造方法 public LinkedHashSet() { /**調(diào)用父類(lèi)HashSet的構(gòu)造方法,dummy只是為了重載加的參數(shù),沒(méi)有具體含義 HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } **/ //默認(rèn)初始數(shù)組長(zhǎng)度16,加載因子為0.75 super(16, .75f, true); } //2.有參構(gòu)造方法,數(shù)組長(zhǎng)度 public LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } //3.有參構(gòu)造方法,數(shù)組長(zhǎng)度及加載因子 public LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); }
2.1.3 添加數(shù)據(jù)
使用父類(lèi)HashSet的添加方法。
2.2 LinkedHashMap
2.2.1 繼承實(shí)現(xiàn)情況
2.2.2 構(gòu)造方法
調(diào)用父類(lèi)HashMap的構(gòu)造方法。
//此參數(shù)是元素排序,等于true的時(shí)候是按哈希值排序,等于false的時(shí)候是按插入順序排序 final boolean accessOrder; //1.無(wú)參構(gòu)造方法 public LinkedHashMap() { super(); accessOrder = false; } //2.有參構(gòu)造方法,數(shù)組長(zhǎng)度 public LinkedHashMap(int initialCapacity) { super(initialCapacity); accessOrder = false; } //3.有參構(gòu)造方法,數(shù)組長(zhǎng)度和加載因子 public LinkedHashMap(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); accessOrder = false; }
2.2.3 擴(kuò)容機(jī)制
新增元素使用父類(lèi)HashMap的put方法,(關(guān)鍵點(diǎn)來(lái)了)LinkedHashMap重寫(xiě)了NewNode方法,使節(jié)點(diǎn)是一個(gè)雙向鏈表節(jié)點(diǎn)。 HashMap的NewNode方法:
Node<K,V> newNode(int hash, K key, V value, Node<K,V> next) { return new Node<>(hash, key, value, next); } //HashMap的內(nèi)部類(lèi)Node static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V> next; Node(int hash, K key, V value, Node<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } public final K getKey() { return key; } public final V getValue() { return value; } public final String toString() { return key + "=" + value; } public final int hashCode() { return Objects.hashCode(key) ^ Objects.hashCode(value); } public final V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } public final boolean equals(Object o) { if (o == this) return true; if (o instanceof Map.Entry) { Map.Entry<?,?> e = (Map.Entry<?,?>)o; if (Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue())) return true; } return false; } }
LinkedHashMap的newNode方法:
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) { LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<K,V>(hash, key, value, e); linkNodeLast(p); return p; } //LinkedHashMap的內(nèi)部類(lèi)Entry<K,V> 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); } } //指針前后指向 private void linkNodeLast(LinkedHashMap.Entry<K,V> p) { LinkedHashMap.Entry<K,V> last = tail; tail = p; if (last == null) head = p; else { p.before = last; last.after = p; } }
到此這篇關(guān)于Java中LinkedHashSet、LinkedHashMap源碼詳解的文章就介紹到這了,更多相關(guān)LinkedHashSet、LinkedHashMap源碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java數(shù)據(jù)結(jié)構(gòu)之HashMap和HashSet
- Java多線(xiàn)程高并發(fā)中解決ArrayList與HashSet和HashMap不安全的方案
- Java HashSet(散列集),HashMap(散列映射)的簡(jiǎn)單介紹
- Java中HashSet和HashMap的區(qū)別_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- java 中HashMap、HashSet、TreeMap、TreeSet判斷元素相同的幾種方法比較
- Java中HashMap和Hashtable及HashSet的區(qū)別
- 淺析Java中Map與HashMap,Hashtable,HashSet的區(qū)別
- Java數(shù)據(jù)結(jié)構(gòu)中的HashMap和HashSet詳解
相關(guān)文章
Springboot定時(shí)任務(wù)Scheduled重復(fù)執(zhí)行操作
這篇文章主要介紹了Springboot定時(shí)任務(wù)Scheduled重復(fù)執(zhí)行操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09詳解RocketMQ中的消費(fèi)者啟動(dòng)與消費(fèi)流程分析
本文主要介紹了RocketMQ的消費(fèi)者啟動(dòng)流程,結(jié)合官方源碼和示例,一步步講述消費(fèi)者在啟動(dòng)和消息消費(fèi)中的的工作原理及內(nèi)容,并結(jié)合平時(shí)業(yè)務(wù)工作中,對(duì)我們所熟悉的順序、push/pull模式等進(jìn)行詳細(xì)分析,以及對(duì)于消息消費(fèi)失敗和重投帶來(lái)問(wèn)題去進(jìn)行分析,需要的朋友可以參考下2022-07-07利用Java多線(xiàn)程技術(shù)導(dǎo)入數(shù)據(jù)到Elasticsearch的方法步驟
這篇文章主要介紹了利用Java多線(xiàn)程技術(shù)導(dǎo)入數(shù)據(jù)到Elasticsearch的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Java調(diào)用第三方http接口的常用方式總結(jié)
這篇文章主要介紹了Java調(diào)用第三方http接口的常用方式總結(jié),具有很好的參考價(jià)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06Java面試synchronized偏向鎖后hashcode存址
這篇文章主要為大家介紹了Java面試中synchronized偏向鎖后hashcode存址詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05IDEA 2020代碼提示忽略大小寫(xiě)的問(wèn)題
這篇文章主要介紹了IDEA 2020代碼提示忽略大小寫(xiě)的問(wèn)題,本文通過(guò)圖文并茂的形式給大家分享解決方法,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07springboot實(shí)現(xiàn)異步調(diào)用@Async的示例
這篇文章主要介紹了springboot實(shí)現(xiàn)異步調(diào)用@Async的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12