一个是链表长度到8(实际是要超过8,后面有补充说明),一个是数组长度到64.
上图所示是判断链表长度到达8调用treeifyBin方法转换红黑树,TREEIFY_THRESHOLD的值为8 ,TREEIFY_THRESHOLD-1=7,所以binCount >=7时调用treeifyBin方法
上图所示是treeifyBin的方法代码,开头有判断数组长度是否小于64,小于则进行扩容,否则转红黑树.MIN_TREEIFY_CAPACITY的值为64.
补充:转红黑树链表长度是要超过8不是达到8,根据 凯_天 的评论提供的补充:
1.测试代码可以看 凯_天 评论
2.当binCount=0,put的第2个元素,binCount 1对应put的第3个元素,1对以此类推,当binCount=7时此时put的是第9个元素,而上面的已经说了binCount >=7时调用treeifyBin方法,所以链表长度是要超过8
2.详细的解释可以看下面代码的注释
/*HaskMap putVal 源码 put ele1,ele2...ele8,ele9*/
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//2.当put第二个元素ele2时,p == tab[i] 即p=ele1 != null所以走else
if ((p = tab[i = (n - 1) & hash]) == null)
//1.当put第一个元素ele1的时候走这个地方,tab[i] =ele1
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
//3.从put第二个元素ele2的时候才开始走以下代码
for (int binCount = 0; ; ++binCount) {
//4.p每次都是从ele1元素开始,可以看序号2的注释
//5.当binCount=0的时候p=ele1,此时如果p.next==null时让p.next=ele2并判断(binCount >= TREEIFY_THRESHOLD - 1)是否满足,满足则触发转红黑树,当前put的值是ele2.
//6.而如果p.next不是null则赋值p=ele2,进行下一次循环binCount++及当binCount=1的时候p=ele2,此时赋值p.next=ele3,当前put的是ele3
//7.综上所诉,binCount 0对应2,1对应3,以此类推7对应9
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
//8.TREEIFY_THRESHOLD - 1 = 7
//9.所以当binCount = 7的时候触发转红黑数,此时put的是ele9,所以是超过8转红黑树
if (binCount >= TREEIFY_THRESHOLD - 1)
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
.....后面代码省略
}