linkedhashmap
簡介linkedhashmap是hashmap的子類;在hashmap的基礎上又用雙向鍊錶來實現的;換句話說:linkedhashmap的所有元素不僅滿足hashmap的資料結構,同時滿足linkedlist的結構,維護著這兩套實現方式;
linkedhashmap類主要是維護雙向鍊錶,其他的工作主要還是在hashmap中實現;
linkedhashmapentry
static
class
linkedhashmapentry
extends
hashmap.node
}
主要變數
transient linkedhashmapentry
head;頭結點,雙鏈表中存在最久的節點;
transient linkedhashmapentry
tail;尾結點,鍊錶中剛加入的節點;
final
boolean accessorder;是否根據訪問順序,改變雙向鍊錶的順序;預設為false
;實現lrucache演算法的主要實現;
linkedhashmap主要實現hashmap的三個空方法
// callbacks to allow linkedhashmap post-actions
void
afternodeaccess
(node
p)void
afternodeinsertion
(boolean evict)
void
afternoderemoval
(node
p)
put()方法
put()方法,還是呼叫hashmap的put()方法,主要區別在於putval()中newnode()方法,會呼叫linkedhashmap自己的newnode()方法;其他都一樣,最後likedhashmap方法實現了;
public v put
(k key, v value)
final v putval
(int hash, k key, v value,
boolean onlyifabsent,
boolean evict)
if(e.hash == hash &&
((k = e.key)
== key ||
(key != null && key.
equals
(k))))
break
; p = e;}}
if(e != null)
}++modcount;if(
++size > threshold)
resize()
;//3 不存在的話,hashmap插入新節點,linkedhashmap有具體的實現;
afternodeinsertion
(evict)
;return null;
}
linkedhashmap的newnode()方法;
//建立新節點,插入雙鏈表尾後,並返回該節點;
node
newnode
(int hash, k key, v value, node
e)//在鍊錶尾插入新節點;
private
void
linknodelast
(linkedhashmapentry
p)}
afternodeaccess():如果根據訪問順序排序,並且訪問的節點不是尾結點;將當前節點從鍊錶中刪除,再插入到尾結點後;
void
afternodeaccess
(node
e)//為尾結點重新賦值;
tail = p;
++modcount;
}}
afternodeinsertion():刪除雙向鍊錶中最老的節點即頭結點;預設情況下removeeldestentry()返回false;lrucache類會重寫,返回true;
void
afternodeinsertion
(boolean evict)
}
get()方法
get():獲取對應的值,並且如果是根據訪問排序,在雙向鍊錶中先刪除當前節點e,再插入到鍊錶尾節點後;改變雙向鍊錶的順序;
public v get
(object key)
remove()方法
remove():完全呼叫hashmap的remove()方法,在刪除之後呼叫afternoderemoval(),將當前節點從雙向鍊錶中刪除;
void
afternoderemoval
(node
e)
lrucache
內部使用linkedhashmap作為成員變數儲存元素;key,value都不能為null;根據linkedhashmap的雙鏈表和是否根據訪問順序排序特性來實現的;主要用於載入框架根據最近最少使用演算法,刪除不常用的,節約空間;
初始化
lrucache
lrucache =
newlrucache
(10)//值被替換或者被刪除
@override
protected
void
entryremoved
(boolean evicted, string key, string oldvalue, string newvalue)
};
put()方法:不存在key對應的節點,建立新的節點,加在雙鏈錶鏈尾;存在的話,將值替換;
public
final v put
(k key, v value)
v previous;
synchronized
(this)}
//entryremoved 為空方法,重寫,手動釋放物件value;
if(previous != null)
//計算當前最大size
trimtosize
(maxsize)
;return previous;
}
trimtosize()方法:put()方法之後,判斷當前size是否大於maxsize,如果大於,刪除最近最少使用的元素(即從雙鏈表頭刪除頭結點)
public
void
trimtosize
(int maxsize)
if(size <= maxsize)
map.entry
toevict = map.
eldest()
;if(toevict == null)
key = toevict.
getkey()
; value = toevict.
getvalue()
; map.
remove
(key)
; size -=
safesizeof
(key, value)
; evictioncount++;}
entryremoved
(true
, key, value, null);}
}
get()方法:存在key對應的節點,直接返回對應的value;不存在,呼叫create(key)方法,該方法預設情況下,返回null;也可以創協create()方法,自己實現;
public
final v get
(k key)
v mapvalue;
synchronized
(this
) misscount++;}
//create過程非同步
v createdvalue =
create
(key);if
(createdvalue == null)
//create()返回的不為null
synchronized
(this
)else}if
(mapvalue != null)
else
}
remove():存在key對應的節點,刪除,並減去size;
public
final v remove
(k key)
v previous;
synchronized
(this)}
if(previous != null)
return previous;
}
所有的分析內容到此結束了。如有問題,請多指教,謝謝! LinkedHashMap簡單解析
原始碼版本1.7 本文參考 1 內部結構 節點的結構 整體結構 插入過程 1 從table的角度看,新的entry需要插入到對應的bucket裡,當有雜湊衝突時,採用頭插法將新的entry插入到衝突鍊錶的頭部。2 從header的角度看,新的entry需要插入到雙向鍊錶的尾部。刪除過程 1 從tab...
LinkedHashMap學習筆記
概述linkedhashmap資料結構相比較於hashmap來說,新增了雙向指標,分別指向前乙個節點 before和後乙個節點 after,從而將所有的節點已鍊錶的形式串聯一起來 hashmap裡面的方法在linkedhashmap進行了重寫 void afternodeaccess nodep v...
LinkedHashMap 實現總結
繼承於hashmap,定義了新的內部類entry用於實現雙向鍊錶儲存記錄的插入或訪問順序 accessorder用於指示鍊錶儲存記錄採用的順序,true為訪問順序,false為插入順序 加入新的記錄時需要更新鍊錶,訪問記錄時需要更新鍊錶 更具accessorder值判斷是否實際更新 removeel...