//数组扩容
final HashMap.Node<K, V>[] resize()
{
//临时数组
HashMap.Node<K, V>[] oldTab = table;
//现在的hash表容量,第一次初始化时为0
int oldCap = (oldTab == null) ? 0 : oldTab.length;
//现在的扩容临界值
int oldThr = threshold;
//新的容量,新的阈值
int newCap, newThr = 0;
//hash表容量不为0时
if (oldCap > 0) {
//如果hash表容量已达到最大临界值,则返回原数组,并且扩容临界值保持不变,否则,
// 数组扩容一倍且扩容后的表不能大于限制值,将扩容临界值(该临界值还未乘以加载因子)翻倍
if (oldCap >= MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return oldTab;
} else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
} else if (oldThr > 0) // 容量用阈值
newCap = oldThr;
else { //第一次创建,使用默认值生成相关参数
newCap = DEFAULT_INITIAL_CAPACITY;
newThr = (int) (DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
}
//第一次扩容初始化阈值
if (newThr == 0) {
float ft = (float) newCap * loadFactor;
newThr = (newCap < MAXIMUM_CAPACITY && ft < (float) MAXIMUM_CAPACITY ?
(int) ft : Integer.MAX_VALUE);
}
//更新扩容临界值
threshold = newThr;
//创建hash表
@SuppressWarnings({"rawtypes", "unchecked"})
HashMap.Node<K, V>[] newTab = (HashMap.Node<K, V>[]) new HashMap.Node[newCap];
table = newTab;
//已存在hash表
if (oldTab != null) {
//遍历hash表中每个桶
for (int j = 0; j < oldCap; ++j) {
//临时节点变量,指向旧桶中的节点元素
HashMap.Node<K, V> e;
//如果旧的hash表的当前桶位置存在节点,将值赋值于e
if ((e = oldTab[j]) != null) {
//另该桶的值为null
oldTab[j] = null;
//如果取出来的节点不存在下一个元素,则重新计算对应新hash桶的位置
if (e.next == null)
newTab[e.hash & (newCap - 1)] = e;
else if (e instanceof HashMap.TreeNode) //红黑树
((HashMap.TreeNode<K, V>) e).split(this, newTab, j, oldCap);
else { // 链表
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; //指向下一个节点
//判断当前节点的hash值的比hash表容量高一位的二进制位是否为1,如果为0,则节点保持原桶,如果为1,到新桶
if ((e.hash & oldCap) == 0) {
if (loTail == null) //原桶位置的链表尾
loHead = e;//将当前节点设置为链表头
else
loTail.next = e; // 当前节点追加到尾节点的下一节点
loTail = e; //将当前节点设置为尾节点
} else {
if (hiTail == null) //同上
hiHead = e;
else
hiTail.next = e;
hiTail = e;
}
} while ((e = next) != null);
if (loTail != null) { // 存在链表
loTail.next = null;
newTab[j] = loHead;
}
if (hiTail != null) { //新桶位置存在链表
hiTail.next = null;
newTab[j + oldCap] = hiHead; //当前桶位置+旧的hash表容量
}
}
}
}
}
return newTab;
}