/**
* Initializes or doubles table size. If null, allocates in
* accord with initial capacity target held in field threshold.
* Otherwise, because we are using power-of-two expansion, the
* elements from each bin must either stay at same index, or move
* with a power of two offset in the new table.
*
* @return the table
*/
final Node<K,V>[] resize() {
Node<K,V>[] oldTab = table;
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;
return oldTab;
}
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
}
else if (oldThr > 0) // initial capacity was placed in threshold
newCap = oldThr;
else { // zero initial threshold signifies using defaults
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;
@SuppressWarnings({"rawtypes","unchecked"})
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
table = newTab;
if (oldTab != null) {
for (int j = 0; j < oldCap; ++j) {
Node<K,V> e;
if ((e = oldTab[j]) != null) {
oldTab[j] = null;
if (e.next == null)
newTab[e.hash & (newCap - 1)] = e;
else if (e instanceof TreeNode)
((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
else { // preserve order
Node<K,V> loHead = null, loTail = null;
Node<K,V> hiHead = null, hiTail = null;
Node<K,V> next;
do {
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) {
loTail.next = null;
newTab[j] = loHead;
}
if (hiTail != null) {
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
}
}
}
}
return newTab;
}
注释
初始化或加倍表的大小。若为空,按字段阈值中持有的初始容量目标分配。否则,由于我们使用的是2的幂展开,每个bin中的元素要么必须保持在相同的索引中,要么在新表中移动2的幂偏移量
第一部分
简述
主要计算map的需要扩容的大小
业务逻辑整理
- 1,如果map有值
- 1.1,map长度大于等于1 << 30 (即1073741824),则设置threshold为最大值
- 1.2,map长度扩大一倍,任然小于1 << 30 (即1073741824),且大于初始值,则设置oldThr (threshold)扩大一倍
- 2,如果map没有值,但是oldThr(threshold)大于0,则不改变oldThr(threshold)大小
- 3,否则(map为空,oldThr小于0),newCap,newThr进行初始化
int oldCap = (oldTab == null) ? 0 : oldTab.length;
int oldThr = threshold;
int newCap, newThr = 0;
// 1,map有值,即oldCap(oldTab(table).length)大于0
if (oldCap > 0) {
//1.1,扩容的长度已经达到最大值,即设置threshold为最大值
if (oldCap >= MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return oldTab;
}
//1.2,扩容的长度没有达到最大值,即设置newThr扩容一倍
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
}
//2如果map没有值,但是oldThr(threshold)大于0,则不改变oldThr(threshold)大小
else if (oldThr > 0) // initial capacity was placed in threshold
newCap = oldThr;
//3,否则(map为空,oldThr小于0),newCap,newThr进行初始化
else { // zero initial threshold signifies using defaults
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;
第二部分
简述
主要重置对象的位置
业务逻辑整理
- 1,如果table 不为空,循环table中对象
- 2,如果e = oldTab[j]对象为空,进入下一个对象
- 3,如果e = oldTab[j]不为空
- 3.1,e对象链表中的下一个对象是为空,则重新计算e对象的下标(e.hash & (newCap - 1)),放入newTab对象中
- 3.2,如果e对象链表中的下一个对象不为空,且是一个树结构,调用split函数,重置对象
- 3.3,否则(即e对象链表中有值,又不是树结构),则循环链表,重置链表中的对象位置
@SuppressWarnings({"rawtypes","unchecked"})
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
table = newTab;
if (oldTab != null) {
//1,如果table 不为空,循环table中对象
for (int j = 0; j < oldCap; ++j) {
Node<K,V> e;
//3,如果e = oldTab[j]不为空
if ((e = oldTab[j]) != null) {
oldTab[j] = null;
//3.1,e对象链表中的下一个对象是为空,则重新计算e对象的下标(e.hash & (newCap - 1)),放入newTab对象中
if (e.next == null)
newTab[e.hash & (newCap - 1)] = e;
//3.2,如果e对象链表中的下一个对象不为空,且是一个树结构,调用split函数,重置对象
else if (e instanceof TreeNode)
((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
//3.3,否则(即e对象链表中有值,又不是树结构),则循环链表,重置链表中的对象位置
else { // preserve order
Node<K,V> loHead = null, loTail = null;
Node<K,V> hiHead = null, hiTail = null;
Node<K,V> next;
do {
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) {
loTail.next = null;
newTab[j] = loHead;
}
//需要移动的元素,计算出下标,元素挂靠对应位置
if (hiTail != null) {
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
}
}
}
}