LinkedHashMap原始碼解讀

2021-09-02 15:23:05 字數 3616 閱讀 3151

1、繼承關係

public class linkedhashmapextends hashmapimplements map
繼承了hashmap類,實現了map介面,即linkedhashmap具有hashmap的特點。

2、基本屬性

private static final long serialversionuid = 3801124242820219131l;

private transient entryheader;//雙向煉表頭節點,也即哨兵節點,裡面不儲存任何資訊

private final boolean accessorder;//有序性標識

由於linkedhashmap具有accessorder標識,因此linkedhashmap能夠實現插入、訪問有序

3、構造方法(總共有5種)

1)傳入的引數為初始容量,載入因子,呼叫了父類的構造方法,按照插入順序

public linkedhashmap(int initialcapacity, float loadfactor)

2)傳入的引數的初始容量,呼叫父類的構造方法,取得鍵值對的順序是插入順序

public linkedhashmap(int initialcapacity)

3)無參構造,呼叫父類的構造方法,取得鍵值對的順序是插入順序

public linkedhashmap()

4)傳入的引數是乙個map的集合,呼叫父類的構造方法,取得鍵值對的順序是插入順序

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

5)傳入的引數為初始容量,載入因子,有序性標識(鍵值對保持順序),呼叫了父類的構造方法

public linkedhashmap(int initialcapacity,

float loadfactor,

boolean accessorder)

從構造方法中可以看出,預設都採用插入順序來維持取出鍵值對的次序。所有構造方法都是通過呼叫父類的構造方法來建立物件的。accessorder:false:插入有序;true:訪問有序

4、基本資料結構(entry)

private static class entryextends hashmap.entry
從基本結構中可以看出:entry具有六個屬性:k key、v value、entrynext、int hash、entrybefore、entryafter。其中前四個屬性是從hashmap中繼承過來的,後面兩個是linkedhashmap獨有的。next是用來維護hashmap指定table位置上鏈結entry順序的,而befor、after是用來維護entry插入的先後順序的。

5、init()

@override

void init()

init()在hashmap中並沒有實際的意義,只是給子類實現相關的初始化呼叫提供的;而在linkedhashmap中重寫了init()方法。

6、核心方法

1)put()方法:新增元素  呼叫的是父類新增元素的方法

public v put(k key, v value) 

if (key == null) //key為null時

return putfornullkey(value);

int hash = hash(key); //通過key計算hash

int i = indexfor(hash, table.length); //計算在陣列中的索引位置

for (entrye = table[i]; e != null; e = e.next)

}modcount++;

addentry(hash, key, value, i); 2 //addentry呼叫的是linkedhashmap重寫了的方法

return null;

}//子類即當前類

void recordaccess(hashmapm)

} 插入有序不做處理,在訪問有序做相應處理:addbefore(將當前節點插到header的前面)

//子類即當前類

private void addbefore(entryexistingentry)

//子類即當前類

void addentry(int hash, k key, v value, int bucketindex)

}//父類hashmap的方法

final entryremoveentryforkey(object key)

int hash = (key == null) ? 0 : hash(key);

int i = indexfor(hash, table.length);

entryprev = table[i];

entrye = prev;

while (e != null)

prev = e;

e = next;

}return e;

}

由原始碼可知:該迴圈雙向鍊錶的頭部存放的是最久訪問的節點或最先插入的節點,尾部為最近訪問的或最近插入的節點,迭代器遍歷方向是從鍊錶的頭部開始到鍊錶尾部結束,在鍊錶尾部有乙個空的header節點,該節點不存放任何內容,是linkedhashmap類的成員屬性,迴圈雙向鍊錶的入口。 

2)get()方法:獲取元素

public v get(object key) 

private static class entryextends hashmap.entry

在hashmap的put和get方法中,會呼叫該方法,在hashmap中該方法為空;在linkedhashmap中,當按訪問順序排序時,該方法會將當前節點插入到鍊錶尾部(頭結點的前乙個節點),否則不做任何事

void recordaccess(hashmapm)

}private void addbefore(entryexistingentry)

由原始碼可知:linkedhashmap重寫了父類hashmap的get方法,實際在呼叫父類getentry()方法取得查詢的元素後,再判斷當排序模式accessorder為true時(即按訪問順序排序),先將當前節點從鍊錶中移除,然後再將當前節點插入到鍊錶尾部。由於的鍊錶的增加、刪除操作是常量級的,故並不會帶來效能的損失。

3)remove()方法:刪除元素

private void remove()
7、linkedhashmap特點總結

1)linkedhashmap可以保證資料的插入、訪問有序(主要取決於accessorder)

2)底層是由陣列和迴圈鍊錶實現的

3)繼承hashmap,具有hashmap的特點,也是執行緒不安全的

4)linkedhashmap中的header是哨兵節點,裡面沒有儲存任何資料

5)應用場景:要想保證資料有序時可以使用

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