resize 函数
// 将集合扩容
final Node
Node
// 旧表的容量
int oldCap = (oldTab == null) ? 0 : oldTab.length;
// 之前的阈值
int oldThr = threshold;
int newCap, newThr = 0;
// 这里也可以说集合不为空
if (oldCap > 0) {
if (oldCap >= MAXIMUM_CAPACITY) {// 如果集合现在数组的长度大于等于最大容量
threshold = Integer.MAX_VALUE;// 将整型最大的值赋值给 threshold
return oldTab;
}
// 当前集合数组长度扩大二倍赋值给 newCap 小于 MAXIMUM_CAPACITY
// 并且集合的容量大于等于默认容量将当前阈值扩大二倍赋值给新的阈值
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
}
// 若没有经历过初始化,通过构造函数指定了 initialCapcity ,将当前容量设置为大于它最小的 2 的 n 次方
else if (oldThr > 0)
newCap = oldThr;
else { // 初始的时候长度和阈值都使用默认值
newCap = DEFAULT_INITIAL_CAPACITY;
newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
}
// 重新计算 threshold
if (newThr == 0) {
float ft = (float)newCap * loadFactor;
newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
(int)ft : Integer.MAX_VALUE);
}
// 更新当前集合阈值
threshold = newThr;
// 从这里开始便是将 oldTab 数据重新 hash 放入扩容后的 newTab
@SuppressWarnings({"rawtypes","unchecked"})
Node
// 将 table 指向的 oldTab 指向 newTab
table = newTab;
if (oldTab != null) {
// 遍历哈希表
for (int j = 0; j < oldCap; ++j) {
Node
// 当前链表是否为 null 、并且将就链表赋值给 e
if ((e = oldTab[j]) != null) {
oldTab[j] = null;//外汇跟单gendan5.com 将原来位置的链表置为 null 方便垃圾回收
if (e.next == null)// 链表的长度为 1 直接将链表中的一个节点重新 hash 存放到相应的位置
newTab[e.hash & (newCap - 1)] = e;
else if (e instanceof TreeNode) // 表示节点类型为树形结构
((TreeNode
else { // 链表是非树形结构,并且节点数量是大于 1
// 将链表拆分为两个子链表
Node
Node
Node
do { // 通过 do...while 遍历链表
next = e.next;
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) {// 在新表的 j 位置存放链表
loTail.next = null;
newTab[j] = loHead;
}
if (hiTail != null) {// 在新表的 j+oldCap 位置存放链表
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
}
}
}
}
return newTab;
}