Java集合之LinkedHashMap常用方法解析
生活随笔
收集整理的這篇文章主要介紹了
Java集合之LinkedHashMap常用方法解析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近正準備回顧一下Java,所以在此做一些記錄。
LinkedHashMap繼承了HashMap,大多數的操作調用的是HashMap的實現,在進行操作的時候多維護了一層雙向鏈表
LinkedHashMap的節點也繼承了HashMap的節點,多維護了前置節點和后置節點兩個屬性
1 static class Entry<K,V> extends HashMap.Node<K,V> {
2 Entry<K,V> before, after;
3 Entry(int hash, K key, V value, Node<K,V> next) {
4 super(hash, key, value, next);
5 }
6 }
View Code
1.put(K key, V value) 存放一個鍵值對,其實是調用了HashMap的put方法,通過重寫HashMap里的部分方法來實現鏈表的維護
1 HashMap的put方法會生成一個節點,調用了newNode方法,而LinkedHashMap重寫了此方法
2 /**
3 * 創建一個節點
4 * @param hash hash值
5 * @param key 鍵
6 * @param value 值
7 * @param e 下一個節點,這個是HashMap節點的屬性
8 * @return
9 */
10 Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
11 //調用構造方法
12 LinkedHashMap.Entry<K,V> p =
13 new LinkedHashMap.Entry<K,V>(hash, key, value, e);
14 //維護鏈表
15 linkNodeLast(p);
16 return p;
17 }
18
19 /**
20 * 添加一個節點到末尾
21 * @param p 節點
22 */
23 private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
24 //保存尾部節點
25 LinkedHashMap.Entry<K,V> last = tail;
26 //更新尾部節點
27 tail = p;
28 //判斷之前的尾部節點是否為空
29 if (last == null)
30 //之前的尾部節點為空,說明還沒有數據,設置一下頭節點
31 head = p;
32 else {
33 //說明之前已經有數據了,將新的節點作為尾部節點連接起來
34 p.before = last;
35 last.after = p;
36 }
37 }
38
39 HashMap當put一個已經存在的key時,會觸發是否更新的操作,之后會調用afterNodeAccess方法,LinkedHashMap重寫了此方法
40 /**
41 * accessOrder為true時,將操作的節點移到鏈表尾部
42 * @param e 節點
43 */
44 void afterNodeAccess(Node<K,V> e) {
45 LinkedHashMap.Entry<K,V> last;
46 //accessOrder 這個參數是指在進行操作的時候,是否將操作的節點移動到鏈表的最后,默認false
47 //也就是說accessOrder為false的時候鏈表就是按照插入順序維護的
48 //true的時候,會將最近使用的節點移動到鏈表最后
49 if (accessOrder && (last = tail) != e) {
50 //保存當前節點和其前置節點和后置節點
51 LinkedHashMap.Entry<K,V> p =
52 (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
53 //清空后置節點,因為當前節點要被移動到最后了
54 p.after = null;
55 //判斷前置節點是否為空節點
56 if (b == null)
57 //前置節點為空,說明當前節點是頭節點,將它的后置節點也就是第二個節點設置為頭節點
58 head = a;
59 else
60 //存在前置節點,將前置節點的后置節點連接到當前節點的下一個節點
61 b.after = a;
62 //判斷后置節點是否為空
63 if (a != null)
64 //后置節點不為空,更新后置節點的前置節點
65 a.before = b;
66 else
67 //說明該節點就是尾部節點,設置前置節點為后節點
68 //a == null 說明p就是尾部節點? 有點不清楚
69 last = b;
70 //統一更新尾部節點
71 if (last == null)
72 //說明只有這么一個節點
73 head = p;
74 else {
75 //將當前節點掛到鏈表末尾
76 p.before = last;
77 last.after = p;
78 }
79 //設置尾部節點
80 tail = p;
81 ++modCount;
82 }
83 }
84
85 LinkedHashMap也重寫了afterNodeInsertion方法
86 void afterNodeInsertion(boolean evict) {
87 LinkedHashMap.Entry<K,V> first;
88 if (evict && (first = head) != null && removeEldestEntry(first)) {
89 K key = first.key;
90 removeNode(hash(key), key, null, false, true);
91 }
92 }
93
94 protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
95 return false;
96 }
97
98 其實LinkedHashMap中這個方法并不生效
View Code
2.get(Object key) 根據key獲取值
1 /**
2 * 獲取值
3 * @param key 鍵
4 * @return
5 */
6 public V get(Object key) {
7 Node<K,V> e;
8 //調用了HashMap中的getNode方法
9 if ((e = getNode(hash(key), key)) == null)
10 return null;
11 if (accessOrder)
12 //移動當前操作的節點到鏈表最后
13 afterNodeAccess(e);
14 return e.value;
15 }
View Code
3.containsValue(Object value) 是否存在某個值
1 public boolean containsValue(Object value) {
2 //通過遍歷鏈表實現
3 for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after) {
4 V v = e.value;
5 if (v == value || (value != null && value.equals(v)))
6 return true;
7 }
8 return false;
9 }
View Code
4.remove(Object key) 刪除key
1 LinkedHashMap調用了HashMap的remove方法
2 重寫了afterNodeRemoval方法
3 /**
4 * 刪除鏈表中的節點
5 * @param e
6 */
7 void afterNodeRemoval(Node<K,V> e) {
8 //獲取當前節點的前置后置節點
9 LinkedHashMap.Entry<K,V> p =
10 (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
11 //清空前置后置節點
12 p.before = p.after = null;
13
14 if (b == null)
15 //前置節點為空,說明為頭節點,更新頭節點為后置節點
16 head = a;
17 else
18 //前置節點不為空,設置前置節點的后置節點為刪除節點的后置節點
19 b.after = a;
20 if (a == null)
21 //后置節點為空,說明為尾部節點,更新尾部節點為其前置節點
22 tail = b;
23 else
24 //后置節點不為空,更新后置節點的前置節點
25 a.before = b;
26 }
View Code
總結
以上是生活随笔為你收集整理的Java集合之LinkedHashMap常用方法解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS开发之主题皮肤
- 下一篇: Nagios远程监控软件的安装与配置详解