LinkedHashMap 原始碼解析

2021-09-21 16:03:25 字數 4382 閱讀 2302

linkedhashmap實現map繼承hashmap,基於map的雜湊表和鏈該列表實現,具有可預知的迭代順序。

linedhashmap維護著乙個執行於所有條目的雙重鍊錶結構,該鍊錶定義了迭代順序,可以是插入或者訪問順序。

linthashmap的節點物件繼承hashmap的節點物件,並增加了前後指標 before after:

/**

* linkedhashmap節點物件

*/static

class entryextends hashmap.node

}

accessorder,簡單說就是這個用來控制元素的順序, 

accessorder為true: 表示按照訪問的順序來,也就是誰最先訪問,就排在第一位 

accessorder為false表示按照存放順序來,就是你put元素的時候的順序。

public linkedhashmap(int initialcapacity, float

loadfactor)

/*** 生成乙個空的linkedhashmap,並指定其容量大小,負載因子使用預設的0.75,

* accessorder為false表示按照存放順序來,就是你put元素的時候的順序

* accessorder為true: 表示按照訪問的順序來,也就是誰最先訪問,就排在第一位

*/public linkedhashmap(int

initialcapacity)

/*** 生成乙個空的hashmap,容量大小使用預設值16,負載因子使用預設值0.75

* 預設將accessorder設為false,按插入順序排序.

*/public

linkedhashmap()

/*** 根據指定的map生成乙個新的hashmap,負載因子使用預設值,初始容量大小為math.max((int) (m.size() / default_load_factor) + 1,default_initial_capacity)

* 預設將accessorder設為false,按插入順序排序.

*/public linkedhashmap(map<? extends k, ? extends v>m)

/*** 生成乙個空的linkedhashmap,並指定其容量大小和負載因子,

* 預設將accessorder設為true,按訪問順序排序

*/public linkedhashmap(int

initialcapacity,

float

loadfactor,

boolean

accessorder)

putmapentries(m,false)呼叫父類hashmap的方法,繼而根據hashmap的put來實現資料的插入:

/**

* implements map.putall and map constructor**

@param

m the map

* @param

evict false when initially constructing this map, else

* true (relayed to method afternodeinsertion).

*/final

void putmapentries(map<? extends k, ? extends v> m, boolean

evict)

else

if (s >threshold)

resize();

for (map.entry<? extends k, ? extends v>e : m.entryset())

}}

put呼叫的hashmap的put方法,呼叫兩個空方法,由linkedhashmap實現

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();

afternodeinsertion(evict);

return

null

; }

在hashmap中紅色部分為空實現:

void afternodeaccess(nodep) 

void afternodeinsertion(boolean evict)

然後看下linkedhashmap怎麼實現這兩方法:

將當前節點e移動到雙向鍊錶的尾部。每次linkedhashmap中有元素被訪問時,就會按照訪問先後來排序,先訪問的在雙向鍊錶中靠前,越後訪問的越接近尾部。當然只有當accessordertrue時,才會執行這個操作。

void afternodeaccess(nodee) 

//尾結點為p

tail =p;

//增加結構性修改數量

++modcount;

}}

afternodeinsertion方法evicttrue時刪除雙向鍊錶的頭節點

void afternodeinsertion(boolean evict) 

}

刪除操作呼叫hashmap的remove方法實現元素刪除,remove呼叫removenode,而removenode有乙個方法需要linkedhashmap來實現:

e節點從雙向鍊錶中刪除,更改e前後節點引用關係,使之重新連成完整的雙向鍊錶。

void afternoderemoval(nodee)

e不為空,則獲取e的value值並返回。

public

v get(object key)

accessorder為true,也就是說按照訪問順序獲取內容。

void afternodeaccess(nodee) 

//尾結點為p

tail =p;

//增加結構性修改數量

++modcount;

}}

linkedhashmap的幾個迭代器:

抽象類linkedha****erator 實現具體刪除,判斷是否存在下個結點,迭代的邏輯。

linkedkeyiterator 繼承自linkedha****erator,實現了iterator介面,對linkedhashmap中的key進行迭代。
linkedvalueiterator 繼承自linkedha****erator,實現了iterator介面,對linkedhashmap中的value進行迭代
linkedentryiterator 繼承自linkedha****erator,實現了iterator介面,對linkedhashmap中的結點進行迭代
abstract

class

linkedha****erator

//是否存在下乙個結點

public

final

boolean

hasnext()

final linkedhashmap.entrynextnode()

//刪除操作

public

final

void

remove()

}final

class linkedkeyiterator extends

linkedha****erator

implements iterator

}final

class linkedvalueiterator extends

linkedha****erator

implements iterator

}final

class linkedentryiterator extends

linkedha****erator

implements iterator>

}

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