HashMap 最小樹形化閾值 MIN_TREEIFY_CAPACITY


HashMap的幾個關鍵參數很重要,大家非常熟悉capacity loadFactory threshold table  size 以及下列jdk1.8后特有的紅黑樹相關參數。其中,最小樹形化參數MIN_TREEIFY_THRESHOLD 的作用到底是什么呢?

/**

* 與紅黑樹相關的參數

*/

// 1. 桶的樹化閾值:即 鏈表轉成紅黑樹的閾值,在存儲數據時,當鏈表長度 > 該值時,則將鏈表轉換成紅黑樹

static final int TREEIFY_THRESHOLD = 8;

// 2. 桶的鏈表還原閾值:即 紅黑樹轉為鏈表的閾值,當在擴容(resize())時(此時HashMap的數據存儲位置會重新計算),在重新計算存儲位置后,當原有的紅黑樹內數量 < 6時,則將 紅黑樹轉換成鏈表

static final int UNTREEIFY_THRESHOLD = 6;

// 3. 最小樹形化容量閾值:即 當哈希表中的容量 > 該值時,才允許樹形化鏈表 (即 將鏈表 轉換成紅黑樹)

// 否則,若桶內元素太多時,則直接擴容,而不是樹形化

// 為了避免進行擴容、樹形化選擇的沖突,這個值不能小於 4 * TREEIFY_THRESHOLD

static final int MIN_TREEIFY_CAPACITY = 64;

 

在我們熟悉的

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict)
方法中並沒有出現最小樹形化參數,並且在鏈表轉成紅黑樹的判斷語句前並沒有相關判斷,頓時頭痛。仔細再核對一遍putVal()中的判斷語句

for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);

// 鏈表長度達到8,進行鏈表轉紅黑樹
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
final void treeifyBin(Node<K,V>[] tab, int hash) {
int n, index; Node<K,V> e;
//判斷capacity是否小於最小樹形化容量閾值
if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
resize();
else if ((e = tab[index = (n - 1) & hash]) != null) {
TreeNode<K,V> hd = null, tl = null;
do {
TreeNode<K,V> p = replacementTreeNode(e, null);
if (tl == null)
hd = p;
else {
p.prev = tl;
tl.next = p;
}
tl = p;
} while ((e = e.next) != null);
if ((tab[index] = hd) != null)
hd.treeify(tab);
}
}
原來MIN_TREEIFY_CAPACITY出現在了treeifyBin()中!這樣做會讓邏輯更清楚,避免了在treeifyBin()前判斷capacity與MIN_TREEIFY_CAPACITY比較的代碼量過大。
————————————————
版權聲明:本文為CSDN博主「Yonyzxr」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Junizxr/article/details/92692544


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM