給jdk寫注釋系列之jdk1.6容器(5)-LinkedHashMap源碼解析
來自: http://www.importnew.com/17561.html
/** * LinkedHashMap entry. */ private static class Entry<K,V> extends HashMap.Entry<K,V> { // These fields comprise the doubly linked list used for iteration. // 雙向鏈表的上一個節點before和下一個節點after Entry<K,V> before, after ; // 構造方法直接調用父類HashMap的構造方法(super) Entry( int hash, K key, V value, HashMap.Entry<K,V> next) { super(hash, key, value, next); } /** * 從鏈表中刪除當前節點的方法 */ private void remove() { // 改變當前節點前后兩個節點的引用關系,當前節點沒有被引用后,gc可以回收 // 將上一個節點的after指向下一個節點 before.after = after; // 將下一個節點的before指向前一個節點 after.before = before; } /** * 在指定的節點前加入一個節點到鏈表中(也就是加入到鏈表尾部) */ private void addBefore(Entry<K,V> existingEntry) { // 下面改變自己對前后的指向 // 將當前節點的after指向給定的節點(加入到existingEntry前面嘛) after = existingEntry; // 將當前節點的before指向給定節點的上一個節點 before = existingEntry.before ; // 下面改變前后最自己的指向 // 上一個節點的after指向自己 before.after = this; // 下一個幾點的before指向自己 after.before = this; } // 當向Map中獲取查詢元素或修改元素(put相同key)的時候調用這個方法 void recordAccess(HashMap<K,V> m) { LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m; // 如果accessOrder為true,也就是使用最近較少使用順序 if (lm.accessOrder ) { lm. modCount++; // 先刪除,再添加,也就相當于移動了 // 刪除當前元素 remove(); // 將當前元素加入到header前(也就是鏈表尾部) addBefore(lm. header); } } // 當從Map中刪除元素的時候調動這個方法 void recordRemoval(HashMap<K,V> m) { remove(); } }
可以看到Entry繼承了HashMap中的Entry,但是LinkedHashMap中的Entry多了兩個屬性指向上一個節點的before和指向下一個節點的after,也正是這兩個屬性組成了一個雙向鏈表。等等。。。Entry還有一個繼承下來的next屬性,這個next是單向鏈表中用來指向下一個節點的,怎么回事嘛,怎么又是單向鏈表又是雙向鏈表呢,都要暈了對不對,其實想的沒錯,這里的節點即是Hash表中的單向鏈表中的一個節點,它又是LinkedHashMap維護的雙向鏈表中的一個節點,是不是瞬間覺得高大上了。圖解一下吧(不要告訴我圖好亂,我看不懂。。。)
本文由用戶 JosefWinfie 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!