給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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!