面試必備:LinkedHashMap原始碼解析(JDK8)
概括的說,LinkedHashMap
是一個關聯陣列、雜湊表,它是執行緒不安全的,允許key為null,value為null。
它繼承自HashMap
,實現了Map<K,V>
介面。其內部還維護了一個雙向連結串列,在每次插入資料,或者訪問、修改資料時,會增加節點、或調整連結串列的節點順序。以決定迭代時輸出的順序。
預設情況,遍歷時的順序是按照插入節點的順序。這也是其與HashMap
最大的區別。
也可以在構造時傳入accessOrder
引數,使得其遍歷順序按照訪問的順序輸出。
因繼承自HashMap
,所以HashMap
上文分析的特點,除了輸出無序,其他LinkedHashMap
LinkedHashMap
在實現時,就是重寫override了幾個方法。以滿足其輸出序列有序的需求。
示例程式碼:
根據這段例項程式碼,先從現象看一下LinkedHashMap
的特徵:
在每次插入資料,或者訪問、修改資料時,會增加節點、或調整連結串列的節點順序。以決定迭代時輸出的順序。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
輸出:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
3 節點
LinkedHashMap
的節點Entry<K,V>
繼承自HashMap.Node<K,V>
,在其基礎上擴充套件了一下。改成了一個雙向連結串列。
- 1
- 2
- 3
- 4
- 5
- 6
同時類裡有兩個成員變數head tail
,分別指向內部雙向連結串列的表頭、表尾。
- 1
- 2
- 3
- 4
- 5
4 建構函式
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
小結:
建構函式和HashMap
相比,就是增加了一個accessOrder
引數。用於控制迭代時的節點順序。
5 增
LinkedHashMap
並沒有重寫任何put方法。但是其重寫了構建新節點的newNode()
方法.
newNode()
會在HashMap
的putVal()
方法裡被呼叫,putVal()
方法會在批量插入資料putMapEntries(Map<?
extends K, ? extends V> m, boolean evict)
或者插入單個數據public
V put(K key, V value)
時被呼叫。
LinkedHashMap
重寫了newNode()
,在每次構建新節點時,通過linkNodeLast(p);
將新節點連結在內部雙向連結串列的尾部。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
以及HashMap
專門預留給LinkedHashMap
的afterNodeAccess()
afterNodeInsertion() afterNodeRemoval()
方法。
- 1
- 2
- 3
- 4