LinkedHashMap原始碼解析

2021-07-10 17:46:51 字數 3079 閱讀 8746

linkedhashmap是hashmap的乙個子類,它保留插入的順序,如果需要輸出的順序和輸入時的相同,那麼就選用linkedhashmap。(這裡的順序指的是插入順序,而不是雜湊表中索引的順序)

linkedhashmap在原始碼中可以看到實現了map介面,並且繼承的是hashmap。也就是採用的map介面的雜湊表和煉表實現的。此實現提供可選的對映操作,並允許使用null值和null鍵。此類不保證對映的順序。

linkedhashmap實現與hashmap的不同之處在於,後者維護著乙個執行於所有條目的雙重鏈結列表。此鏈結列表定義了迭代順序,可順序訪問雜湊表中的結點,這個迭代順序可以是插入順序也可以是訪問順序。

注意,linkedhashmap不是同步的。

根據鍊錶中元素的順序可以分為兩種:按插入順序的鍊錶,按訪問順序的鍊錶。(按照訪問順序的鍊錶是指在呼叫get()方法訪問乙個鍊錶中元素後,會將這次訪問的元素移至鍊錶的尾部,那麼eldest的鍊錶元素是在鍊錶頭部,所以當我們需要刪除訪問次數最少的鍊錶元素時就可以呼叫removeeldest()方法)

linkedhashmap採用的hash演算法和hashmap相同,但是它重新定義了陣列中儲存的元素entry,該entry除了儲存當前物件的引用外,還儲存了其上乙個元素before和下乙個元素after的引用,很顯然是雙向鍊錶的特點,從而在雜湊表的基礎上又構成了雙向鏈結列表。

/**

* hashmap.node subclass for normal linkedhashmap entries.

*/static class

entry

extends

hashmap.node }

以下是hashmap的entry

static class nodeimplements map.entry

public final k getkey()

public final v getvalue()

public final string tostring()

public final int

hashcode()

public final v setvalue(v newvalue)

public final boolean equals(object o)

return

false;}}

linkedhashmap初始化

linkedhashmap呼叫了父類的初始化方法

public

linkedhashmap(int initialcapacity, float loadfactor)

那就來看一下hashmap中的初始化方法:

public

hashmap(int initialcapacity, float loadfactor)

在hashmap中進行載入因子和閾值的初始化,一般hashmap的初始載入因子為0.75

linkedhashmap儲存

這裡並沒有採用hashmap中的put()方法

// link at the end of list

private

void

linknodelast(linkedhashmap.entryp)

}

hashmap中的put方法

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;}}

v oldvalue = e.value;

if (!onlyifabsent || oldvalue == null)

e.value = value;

afternodeaccess(e);

return oldvalue;}}

++modcount;

if (++size > threshold)

resize();

afternodeinsertion(evict);

return

null;

}

通過hash值對映到陣列中,當size大於閾值的時候就進行resize()。

在linkedhashmap中,當有新元素加入鍊錶中時,在afternodeinsertion中呼叫了removeeldestentry(),這裡其實就是lrucache實現元素過期機制的地方,刪除最少使用鍊錶中元素的使用。在預設情況下,removeeldestentry()返回false表示元素永不過期:

void afternodeinsertion(boolean evict) 

}

這裡預設返回的是false

protected

boolean

removeeldestentry(map.entryeldest)

linkedhashmap讀取
public v get(object key)
當我們讀取過這個元素後,要將這個元素移動至鍊錶尾部,以更新鍊錶的最新訪問順序。

void afternodeaccess(nodee) 

tail = p;

++modcount;}}

linkedhashmap幾乎和hashmap一樣,不同的是它定義了乙個entr

AbstractCollection原始碼分析

abstractcollection抽象類提供了collection的骨架實現,collection分析請看 這裡直接看它的 是如何實現的.public abstract iterator iterator 該方法沒有實現.public abstract int size 該方法沒有實現.publi...

ThreadPoolExecutor原始碼閱讀

執行緒池解決兩個問題 一是復用執行緒,減少建立銷毀執行緒帶來系統開銷 二是限定系統資源使用邊界,避免大量執行緒消耗盡系統記憶體 適用於互不依賴,執行時間短,不需要對執行緒控制操作的執行緒 新增任務時,1.若執行緒數量小於corepoolsize,則新增執行緒執行任務 2.若執行緒數量大於等於core...

OrangePi One Android 原始碼編譯

一 系統環境搭建參照 二 lichee原始碼編譯 1.檢視help build.sh h2.配置核心 cd linux 3.4 make arch arm menuconfig 進入配置頁面,上下移動列表,空格是選擇列表,左右移動選擇退出選項 3.首次編譯執行清除 在 lichee linux3.4...