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