我們常說linkedhashmap是有序的,這個有序也是分為兩種的,分別是:插入順序和訪問順序,我們可以通俗的認為:linkedhashmap = hashmap + 雙向鍊錶
以下的學習是基於jdk8
根據linkedhashmap的結構來看,是依賴於hashmap的,通過檢視原始碼,我們也會發現,linkedhashmap只是維護了乙個鍊錶,並沒有put、remove方法的具體實現,因為linkedhashmap的設計思想是:對資料的操作,是依賴於hashmap中的方法,只是在其中的一些細節方法,linkedhashmap會進行擴充套件,接下來我們先說屬性有哪些
/**
* the head (eldest) of the doubly linked list.
* 鍊錶的head節點
*/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: true
* for access-order, false for insertion-order.
* false:表示插入順序;true表示讀取順序
* @serial
*/final
boolean accessorder;
該屬性是來區分當前linkedhashmap是按照訪問順序排序,還是按照put順序有序,當該引數為true的時候,表示按照讀取順序有序;預設為false,按照put順序有序
在呼叫put方法的時候,會呼叫父類hashmap的put方法,那linkedhashmap如何維護節點之間的順序呢?
在put方法中,如果得到當前key要儲存的位置,會呼叫newnode()方法,初始化乙個node節點,
linkedhashmap對該方法,進行了覆寫,
/**
* 在向map中put元素的時候,是會初始化乙個node節點,如果是linkedhashmap,呼叫的是該方法
* 在該方法中,可以看到,會初始化乙個linkedhashmap.entry節點,然後將該節點插入到linkedhashmap的雙向鍊錶中
* 預設是加到鍊錶尾部
* @param hash
* @param key
* @param value
* @param e
* @return
*/node
newnode
(int hash, k key, v value, node
e)
這裡可以看到,除了初始化乙個節點之外,還會呼叫linknodelast方法,在linkednodelast方法中,會將p節點新增到自己維護的雙向鍊錶的尾部
/**
* 這是加入到鍊錶尾部的方法
* 如果當前是第乙個put的元素,那p就是head,否則,就把節點放到tail的後面
* @param p
*/private
void
linknodelast
(linkedhashmap.entry
p)}
假如在初始化linkedhashmap物件的時候,指定accessorder為true,那表示按照訪問順序有序,在get方法中,會對訪問到的元素進行處理
public v get
(object key)
這裡可以看到,如果是按照訪問順序有序的話,會額外呼叫afternodeaccess()方法,如果為false,會直接返回獲取到的節點value值,afternodeaccess方法簡單而言,就是將e節點移到鍊錶的尾部,所以,我們可以認為,最近訪問的在元素在鍊錶的最後面
所以:對於按照put順序有序的設定,在put元素的時候,本身就會把最新插入的元素放入到鍊錶的尾部,如果是按照訪問順序有序的話,在get的時候,會把訪問的元素移到鍊錶的尾部,根據該特點,也可以實現乙個簡單的lru演算法
對於hashmap和linkedhashmap來說,最大的區別就是:hashmap是無序的,linkedhashmap自己維護了節點的順序
LinkedHashMap是如何組織資料的
linkedhashmap繼承自hashmap,底層仍然是陣列加鍊表,除了發生衝突後的單鏈表,它還維護了乙個鏈結所有元素的雙鏈表,這樣就能記錄元素的插入或者訪問順序了。所以linkedhashmap可以做到有序迭代,也可以作為lru演算法的基石。linkedentryheader static cl...
LinkedHashMap 是如何實現的
linkedhash 底層基於 hashmap 實現並擴充套件了 hashmap.node 使其支援雙向鍊錶 示例 hashmaphashmap new hashmap linkedhashmaplinkedhashmap new linkedhashmap for int i 0 i 10 i s...
LinkedHashMap簡單解析
原始碼版本1.7 本文參考 1 內部結構 節點的結構 整體結構 插入過程 1 從table的角度看,新的entry需要插入到對應的bucket裡,當有雜湊衝突時,採用頭插法將新的entry插入到衝突鍊錶的頭部。2 從header的角度看,新的entry需要插入到雙向鍊錶的尾部。刪除過程 1 從tab...