HashMap底層資料結構之鍊表轉紅黑樹的具體時機

2021-09-27 05:12:17 字數 1918 閱讀 9146

1、從hashmap中有關「鍊錶轉紅黑樹」閾值的宣告;

2、【重點】解析hashmap.put(k key, v value)的原始碼;

3、測試;

hashmap中有關「鍊錶轉紅黑樹」閾值的宣告:

/**

* 使用紅黑樹(而不是鍊錶)來存放元素。當向至少具有這麼多節點的鍊錶再新增元素時,鍊錶就將轉換為紅黑樹。

* 該值必須大於2,並且應該至少為8,以便於刪除紅黑樹時轉回鍊錶。

*/static final int treeify_threshold = 8;

/*** 當桶陣列容量小於該值時,優先進行擴容,而不是樹化:

*/static final int min_treeify_capacity = 64;

通過檢視hashmap的原始碼可以發現,它的put(k key, v value)方法呼叫了putval(int hash, k key, v value, boolean onlyifabsent, boolean evict)來實現元素的新增。所以我們實際要看的是putval(int hash, k key, v value, boolean onlyifabsent, boolean evict)的原始碼。

final v putval(int hash, k key, v value, boolean onlyifabsent, boolean evict) 

…… p = e;

} }

…… }

…… }

通過原始碼解析,我們已經很清楚hashmap是在「當鍊表已經有8個節點了,此時再新鏈上第9個節點,在成功新增了這個新節點之後,立馬做鍊錶轉紅黑樹」。

1. 自定義乙個類:該類中去重寫hashcode(),讓一組資料能得到同樣的雜湊值,從而實現雜湊碰撞。同時也重寫equals()方法。

public class a03bean 

/*** 重寫hashcode()方法,只要是4的倍數,最後算出的雜湊值都會是0.

*/@override

public int hashcode()

/*** 也必須重寫equals()方法。當發生雜湊衝突的時候,需要呼叫equals()方法比較兩個物件的實際內容是否相同。

*/@override

public boolean equals(object obj)

}

2. 將自定義類a03bean的例項放到hashmap中:

public class a03method_treeifybin2 

}}

3.debug,斷點檢視當同乙個桶上的鍊錶的長度達到多長時會做「鍊錶轉紅黑樹」的操作。

斷點打在hashmap.putval(int hash, k key, v value, boolean onlyifabsent, boolean evict)方法的「treeifybin(tab, hash);」這裡。

4.測試結果:

當put進第9個元素(hashmap.put(new a03bean(36), 8);)時,hashmap做了鍊錶轉紅黑樹的操作。

也就是說:當鍊表已經有8個元素了,此時put進第9個元素,先完成第9個元素的put,然後立刻做鍊錶轉紅黑樹。這個結論和第2點中得到的結論一致。

最後的輸出結果也證明了所有的元素都成功put進了集合中,hashmap.size等於11。

到這裡,有關「hashmap的鍊錶轉紅黑樹的具體時機」算是解釋清楚了,有時間再**「hashmap的紅黑樹轉回鍊錶的具體時機」。

HashMap底層資料結構

jdk1.8之前 陣列 鍊錶 jdk1.8之後 陣列 鍊錶 紅黑樹 陣列的時間複雜度 o 1 鍊錶的時間複雜度 o n 紅黑樹時間複雜度 o logn 為什麼使用陣列?陣列的的讀 寫速度快。查詢快,增刪慢 為什麼使用鍊錶?為了避免資料的key產生雜湊碰撞後將原有的陣列下標對應的值直接替換。查詢慢,增...

回顧 HashMap的底層資料結構

假設一段 hashmap map newhashmap map.put 張三 測試資料 map.put 李四 測試資料 對張三這個key,計算出hash值,對hash值進行取模處理,定位到陣列裡的乙個元素中去 張三,測試資料 李四,測試資料 如 map.put 張三 測試資料 對 張三 這個key計...

初步了解HashMap底層資料結構

本文主要講述hashmap的一些簡單原理,如果講的不好,可以說出來,讓我改正本文。說到hashmap的資料結構,就需要說到資料結構中的陣列和單鏈表結構,因為hashmap的底層就是陣列和鍊錶,不過這是jdk1.7版本的,1.8版本後加入了紅黑樹。下面先介紹一些這些資料結構。陣列儲存區間是連續的,占用...