LinkedHashMap原始碼閱讀

2021-06-26 20:48:19 字數 4235 閱讀 6883

linkedhashmap內部採用了雜湊表和煉表實現map介面,並可以保證迭代的順序,和hashmap不同,其內部維護乙個指向所有元素的雙向鍊錶,其決定了遍歷的順序,通常是元素插入的順序進行迭代,不過元素重新插入順序不會受到影響。

linkedhashmap提供乙個特殊的建構函式,實現了每次迭代返回最近使用的元素,這個特性可以用於構建lru快取。

此外removeeldestentry(map.entry)方法可以被子類覆蓋用於判斷在新增元素的時候什麼時候可以刪除元素。

linkedhashmap效能同樣受到初始容量和裝填因子的影響,對於基本操作(add,contains,remove)在常數時間內,其效能比hashmap稍微低,由於需要額外代價維護鍊錶;不過其遍歷性能為o(size)高於hashmapo(capacity)。

類定義

直接繼承了hashmap

public

class

linkedhashmap

v>

extends

hashmap

v>

implements

mapv>

成員

private

transient

entry

v>

header

;//用於遍歷的雙向煉表表頭

/** * the iteration ordering method for this linked hash map:

* true: for access-order, false: for insertion-order

*/private

final

boolean

accessorder

;

entry內部類繼承了hashmap.entry類,增加了兩個指標before和after用於維護遍歷順序,實際上entry有三個指標父類本身有個next指標用於當發生元素衝突時指向的下乙個元素。由此可以看出用於遍歷的雙向鍊錶直接加在entry上面,這樣有效節約了空間,實際只比hashmap多了2*size個引用+1個頭結點空間消耗。before和after這兩個引用在外部類呼叫put或remove時,呼叫其相關方法進行維護(recordaccess和recordremoval等)。

private

static

class

entry

v>

extends

hashmap

.entry

v>

private

void

remove

()//existingentry之前新增當前節點

private

void

addbefore

(entry

v>

existingentry

)//由父類hashmap的put方法呼叫,若是acessorder,則新增到雙向鍊錶的頭結點後面;本身get方法也會觸發呼叫

void

recordaccess

(hashmap

v>m)

}//有元素刪除時,呼叫該方法

void

recordremoval

(hashmap

v>m)

}

put方法是繼承自父類hashmap,重寫了當需要新增元素時候呼叫的addentry方法,同樣是在對應桶的煉表頭結點後面新增,新增完以後不是直接進行resize判斷,而是判斷是否要刪除舊的元素,這個方法預設返回false,使用者可以重寫這個方法用於確定快取的淘汰機制。

void

addentry

(int

hash

,k key

,v value

,int

bucketindex

)else

}void

createentry

(int

hash

,k key

,v value

,int

bucketindex

)protected

boolean

removeeldestentry

(map

.entry

v>

eldest

)

get方法

public

v get

(object

key)

//重寫父類方法,效率更高o(size)

public

boolean

containsvalue

(object

value

)else

return

false

;}

linkedhashmap同樣繼承了建立3個集合類檢視:鍵集合、值集合、鍵值對集合的方法,由於額外維護乙個雙向鍊錶保證迭代順序,重寫了相關檢視的迭代器實現,linkedha****erator通過直接迭代鍊錶的header指標來實現指定順序遍歷。

iterator

<

k>

newkeyiterator

()iterator

<

v>

newvalueiterator

()iterator

<

map.

entry

v>>

newentryiterator

()private

class

keyiterator

extends

linkedha****erator

<

k>

}private

class

valueiterator

extends

linkedha****erator

<

v>

}private

class

entryiterator

extends

linkedha****erator

<

map.

entry

v>>

}private

abstract

class

linkedha****erator

<

t>

implements

iterator

<

t>

public

void

remove

()entry

v>

nextentry

()}

linkedhashmap繼承自hashmap,相關基本操作效能略低於hashmap,由於需要額外代價維護鍊錶。其遍歷操作是通過操作該雙向鍊錶實現,而非內部雜湊表陣列,因此效能為o(size)比hashmapo(capacity)更高。

支援兩種順序遍歷:元素插入順序(重複put不算)和最近使用優先順序(呼叫put和get類似lru),預設是按照元素插入順序遍歷。通過建構函式傳入true可以實現最近使用優先遍歷,每次put或get操作時,將該元素直接重新放置到煉表頭結點後面來實現最近使用優先遍歷。

linkedhashmap並沒有重新建立乙個新的鍊錶來實現順序遍歷,而是在每個entry上多加了兩個指標來決定遍歷順序,有效節約了空間消耗。實際只比hashmap多了2*size個引用+1個頭結點空間消耗。

linkedhashmap支援元素淘汰策略,可以通過重寫removeeldestentry方法,來決定呼叫put時候是否需要刪除舊的元素。linkedhashmap可以用於實現lru快取,並自定義元素淘汰策略。

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...