1. linkedhashmap概述:
linkedhashmap是map介面的雜湊表和鏈結列表實現,具有可預知的迭代順序。此實現提供所有可選的對映操作,並允許使用null值和null鍵。此類不保證對映的順序,特別是它不保證該順序恆久不變。
linkedhashmap實現與hashmap的不同之處在於,後者維護著乙個執行於所有條目的雙重鏈結列表。此鏈結列表定義了迭代順序,該迭代順序可以是插入順序或者是訪問順序。
注意,此實現不是同步的。如果多個執行緒同時訪問鏈結的雜湊對映,而其中至少乙個執行緒從結構上修改了該對映,則它必須保持外部同步。
2. linkedhashmap的實現:
對於linkedhashmap而言,它繼承與hashmap、底層使用雜湊表與雙向鍊錶來儲存所有元素。其基本操作與父類hashmap相似,它通過重寫父類相關的方法,來實現自己的鏈結列表特性。下面我們來分析linkedhashmap的源**:
1) entry元素:
linkedhashmap採用的hash演算法和hashmap相同,但是它重新定義了陣列中儲存的元素entry,該entry除了儲存當前物件的引用外,還儲存了其上乙個元素before和下乙個元素after的引用,從而在雜湊表的基礎上又構成了雙向鏈結列表。看源**:
1/**
2* 雙向鍊錶的表頭元素。 3*/
4private transient entryheader; 56
/**
7* linkedhashmap的entry元素。 89
*/10
private
static
class entryextends hashmap.entry
2) 初始化:
public linkedhashmap(int initialcapacity, floatloadfactor)
1public hashmap(int initialcapacity, float
loadfactor)
我們已經知道linkedhashmap的entry元素繼承hashmap的entry,提供了雙向鍊錶的功能。在上述hashmap的構造器
中,最後會呼叫init()方法,進行相關的初始化,這個方法在hashmap的實現中並無意義,只是提供給子類實現相關的初始化呼叫。
linkedhashmap重寫了init()方法,在呼叫父類的構造方法完成構造後,進一步實現了對其元素entry的初始化操作。
voidinit()
3) 儲存:
linkedhashmap並未重寫父類hashmap的put方法,而是重寫了父類hashmap的put方法呼叫的子方法void addentry(int hash, k key, v value, int bucketindex) 和void createentry(int hash, k key, v value, int bucketindex),提供了自己特有的雙向鏈結列表的實現。
1void addentry(int hash, k key, v value, int
bucketindex) else
13} 14
15void createentry(int hash, k key, v value, int
bucketindex)
2324
private
void addbefore(entryexistingentry)
4) 讀取:
linkedhashmap重寫了父類hashmap的get方法,實際在呼叫父類getentry()方法取得查詢的元素後,再判斷當排序模式accessorder為true時,記錄訪問順序,將最新訪問的元素新增到雙向鍊錶的表頭,並從原來的位置刪除。由於的鍊錶的增加、刪除操作是常量級的,故並不會帶來效能的損失。
1public v get
(object key)
1011
void recordaccess(hashmapm)
20 }
5) 排序模式:
linkedhashmap定義了排序模式accessorder,該屬性為boolean型變數,對於訪問順序,為true;對於插入順序,則為false。
private final boolean accessorder;
一般情況下,不必指定排序模式,其迭代順序即為預設為插入順序。看linkedhashmap的構造方法,如:
public linkedhashmap(int initialcapacity, floatloadfactor)
這些構造方法都會預設指定排序模式為插入順序。如果你想構造乙個linkedhashmap,並打算按從近期訪問最少到近期訪問最多的順序(即訪問順序)來儲存元素,那麼請使用下面的構造方法構造linkedhashmap:
public linkedhashmap(intinitialcapacity,
float
loadfactor,
boolean accessorder)
該雜湊對映的迭代順序就是最後訪問其條目的順序,這種對映很適合構建lru快取。linkedhashmap提供了removeeldestentry(map.entryeldest)方法,在將新條目插入到對映後,put和 putall將呼叫此方法。該方法可以提供在每次新增新條目時移除最舊條目的實現程式,預設返回false,這樣,此對映的行為將類似於正常對映,即永遠不能移除最舊的元素。
protected boolean removeeldestentry(map.entryeldest)
此方法通常不以任何方式修改對映,相反允許對映在其返回值的指引下進行自我修改。如果用此對映構建lru快取,則非常方便,它允許對映通過刪除舊條目來減少記憶體損耗。
例如:重寫此方法,維持此對映只儲存100個條目的穩定狀態,在每次新增新條目時刪除最舊的條目。
privatestatic final int max_entries = 100
; protected
boolean removeeldestentry(map.entry eldest)
LinkedHashMap原始碼分析及實現LRU演算法
ps 要先了解hashmap的實現原理hashmap原始碼分析 可以看到linkedhashmap繼承了hashmap,其實際是在hashmap基礎上,把資料節點連成乙個雙向鍊錶,遍歷的時候按鍊錶順序遍歷。小總結預設的linkedhashmap 的遍歷會按照插入的順序遍歷出來,hashmap則不保證...
LinkedHashMap簡單解析
原始碼版本1.7 本文參考 1 內部結構 節點的結構 整體結構 插入過程 1 從table的角度看,新的entry需要插入到對應的bucket裡,當有雜湊衝突時,採用頭插法將新的entry插入到衝突鍊錶的頭部。2 從header的角度看,新的entry需要插入到雙向鍊錶的尾部。刪除過程 1 從tab...
LinkedHashMap學習筆記
概述linkedhashmap資料結構相比較於hashmap來說,新增了雙向指標,分別指向前乙個節點 before和後乙個節點 after,從而將所有的節點已鍊錶的形式串聯一起來 hashmap裡面的方法在linkedhashmap進行了重寫 void afternodeaccess nodep v...