LinkedHashMap原始碼分析及底層原理

2021-10-25 15:24:35 字數 2433 閱讀 5038

linkedhashmap是hashmap 的子類

linkedhashmap 擁有 hashmap 的所有特性,它比 hashmap 多維護了乙個雙向鍊錶,因此可以按照插入的順序從頭部或者從尾部迭代,是有序的,不過因為比 hashmap 多維護了乙個雙向鍊錶,它的記憶體相比而言要比 hashmap 大,並且效能會差一些,但是如果需要考慮到元素插入的順序的話, linkedhashmap 不失為一種好的選擇

雙向鍊錶的實現:通過繼承hashmap中node類,新增before和after屬性,用以串聯節點形成雙向鍊錶,同時新增表頭和表尾屬性,用以標識雙向鍊錶

該類繼承hashmap,表明擁有hashmap的一切特性

public

class

linkedhashmap

extends

hashmap

implements

map

/**

* the head (eldest) of the doubly linked list.

*///維護的雙向鍊錶的表頭

transient linkedhashmap.entry

head;

/*** the tail (youngest) of the doubly linked list.

*///維護的雙向鍊錶的表尾

transient linkedhashmap.entry

tail;

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

* for access-order, for insertion-order.

*///accessorder設定為false,表示不是訪問順序而是插入順序儲存的,這也是預設值,表示linkedhashmap中儲存的順序是按照呼叫put方法插入的順序進行排序的。

final

boolean accessorder;

插入順序是指:每次插入乙個包裝新key-value的新節點,找到陣列索引後放入陣列引用桶中,同時將新節點插入維護的雙向煉表表尾:操作after/before的指向即可完成

訪問順序是指:每次訪問後將維護的雙向煉表表頭的節點移動到表尾

還是原hashmap的,多了兩個引用before,after,表示節點本身增加了鏈結其他節點的功能,從而能夠在節點間維護乙個雙向鍊錶,保證插入或者訪問順序

在hashmap 的節點的基礎上, 加上了兩個引用before, after來將所有節點串聯成乙個雙向鍊錶。

/**

* hashmap.node subclass for normal linkedhashmap entries.

*/static

class

entry

extends

hashmap.node

}

主要就是呼叫hashmap建構函式初始化了乙個node table

public

linkedhashmap

(int initialcapacity,

float loadfactor)

public

linkedhashmap

(int initialcapacity)

public

linkedhashmap()

linkedhashmap 重寫了get() 方法,在afternodeaccess()函式中,會將當前被訪問到的節點e,移動至內部的雙向鍊錶的尾部。

public v get

(object key)

// 唯一需要關注的就是在插入模式中,獲取值後又一次進行把當前節點移到鍊錶尾部操作

//當然這是要基於訪問順序排序時才生效

實現的邏輯: 根據hash值找到雜湊位置i,先判斷table[i]是否存在node ,如果不存在,則呼叫newnode()並賦值給table[i],如果存在,則插入到單鏈表或紅黑樹的後面。

//在構建新節點時,構建的是`linkedhashmap.entry` 不再是`node`.

node

newnode

(int hash, k key, v value, node

e)// link at the end of list

private

void

linknodelast

(linkedhashmap.entry

p)}

重寫後的newnode 只新增了一條邏輯, 把節點新增到雙鏈表的尾部,從而保持住插入順序。

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