链表转红黑树部分源码:
//用来衡量是否要转红黑树的重要参数
static final int TREEIFY_THRESHOLD = 8;
//转红黑树需要的最小数组长度
static final int MIN_TREEIFY_CAPACITY = 64;
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
// TREEIFY_THRESHOLD - 1=7,也就是说一旦binCount=7时就会执行下面的转红黑树代码
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
final void treeifyBin(Node<K,V>[] tab, int hash) {
int n, index; Node<K,V> e;
//这里的tab指的是本HashMap中的数组,n为数字长度,如果数组为null或者数组长度小于64
if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
//则调用resize()方法直接扩容,不转红黑树
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);
}
}
首先要满足【binCount >= TREEIFY_THRESHOLD - 1】这个条件才会走到转红黑树的方法里,那么这时的链表元素到底有多少?
可以知道【TREEIFY_THRESHOLD - 1】=7,所以binCount=7时才会转红黑树,而binCount初始赋值是0,++count是先加再用,所以其实binCount是从1开始的,1,2,3,4,5,6,7,每一个数值对应的都会创建一个newNode,所以binCount到数值7时,创建了7个新的Node节点,但是不要忘了,我们创建的节点都是p.next,也就是p的后继节点,所以加上原来的p节点,也可以理解成是链表首节点,7+1=8,就是8个节点,所以链表里元素数目到8个时,会开始转红黑树。
总结
所以当链表元素数目到8个,同时HashMap的数组长度要大于64,链表才会转红黑树,否则都是做扩容。