链表的扩容
HashMap.Node<K,V> loHead = null, loTail = null;
HashMap.Node<K,V> hiHead = null, hiTail = null;
HashMap.Node<K,V> next;
do {
next = e.next;
/*为什么要和老的数组长度按位与?因为:
数组长度都是2的幂次方,都是00000100000这种的,所以(e.hash & oldCap)的值是否为0,完全取决于oldCap里面的唯一的一个"1"
要么是0,要么不是0
扩容后的位置,要么在原来的位置不变,要么是oldindex+oldCap(原来的下标位置+原来的数组长度)
*/
if ((e.hash & oldCap) == 0) {//要么在原来的位置不变
if (loTail == null)
loHead = e;
else
loTail.next = e;
loTail = e;
}
else {//要么是oldindex+oldCap(原来的下标位置+原来的数组长度)
if (hiTail == null)
hiHead = e;
else
hiTail.next = e;
hiTail = e;
}
} while ((e = next) != null);
/*
循环结束后,再去放置到新数组上面去:
jdk1.8里面是先分组,再放置,分为低位组和高位组,要么在原来的位置不变,要么是oldindex+oldCap(原来的下标位置+原来的数组长度)
*/
if (loTail != null) {//低位组
loTail.next = null;
newTab[j] = loHead;
}
if (hiTail != null) {//高位组
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
红黑树的扩容
final void split(HashMap<K,V> map, Node<K,V>[] tab, int index, int bit) {
TreeNode<K,V> b = this;
// Relink into lo and hi lists, preserving order
TreeNode<K,V> loHead = null, loTail = null;
TreeNode<K,V> hiHead = null, hiTail = null;
int lc = 0, hc = 0;
//将红黑树拆分成两个链表,这里的逻辑和上面的差不多
for (TreeNode<K,V> e = b, next; e != null; e = next) {
next = (TreeNode<K,V>)e.next;
e.next = null;
if ((e.hash & bit) == 0) {
if ((e.prev = loTail) == null)
loHead = e;
else
loTail.next = e;
loTail = e;
++lc;
}
else {
if ((e.prev = hiTail) == null)
hiHead = e;
else
hiTail.next = e;
hiTail = e;
++hc;
}
}
//低位的不为空,则转移低位
if (loHead != null) {
//小于6,则转成链表
if (lc <= UNTREEIFY_THRESHOLD)
tab[index] = loHead.untreeify(map);
//否则,转成红黑树
else {
tab[index] = loHead;
//如果hiHead为null,则直接整个树移过去就可以,否则还要树化低位的
if (hiHead != null) // (else is already treeified)
loHead.treeify(tab);
}
}
if (hiHead != null) {
if (hc <= UNTREEIFY_THRESHOLD)
tab[index + bit] = hiHead.untreeify(map);
else {
tab[index + bit] = hiHead;
if (loHead != null)
hiHead.treeify(tab);
}
}
}