一个是链表长度到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;
			}
		}
		.....后面代码省略
}

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐