静态变量
// 序列号版本UID编号 , 用于序列化
private static final long serialVersionUID = 362498820763181265L;
// 默认初始容量 2^4 = 16 , 必须是2的倍数
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
// 最大容量 = 2^30
static final int MAXIMUM_CAPACITY = 1 << 30;
// 默认扩容因子 = 0.75f
static final float DEFAULT_LOAD_FACTOR = 0.75f;
// 默认链表转换红黑树阈值 = 8
static final int TREEIFY_THRESHOLD = 8;
// 默认由红黑树转换链表的阈值 = 6
static final int UNTREEIFY_THRESHOLD = 6;
// 默认链表转化红黑树的最小容量值 = 64 , 至少是TREEIFY_THRESHOLD的4倍
static final int MIN_TREEIFY_CAPACITY = 64;
成员变量
// hash表数据
transient Node<K, V>[] table;
// Set集
transient Set<Entry<K, V>> entrySet;
// 大小
transient int size;
// modCount
transient int modCount;
// 扩容容量阈值
int threshold;
// 扩容因子
final float loadFactor;
扩容
1.获取扩容容量阈值newThr和新表容量newCap(newThr)
- 旧表有数据,newThr2,newCap看情况2/MAX/Default
- 旧表无数据,oldThr > 0,newCap=oldThr,新容量等于旧扩容容量阈值
- 其他情况赋默认值
- 最后防止newThr超出最大值
- threshold = newThr
2.生成新表,copy旧表数据
- table = newTab = new Node[newCap]
- 数组形式:更新新地址下标hashcode & newCap - 1
- 红黑树形式:split
- 链表形式:原链表根据hascode & oldCap 值[0,1]一分为二,0位置不动 / 1位置增加扩容长度
// 扩容
final Node<K, V>[] resize() {
// 旧表 = 类成员表
Node<K, V>[] oldTab = table;
// 旧表容量初始化 0 / length
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; }
}
// 旧表未初始化,且旧扩容容量阈值 > 0,新容量 = 旧扩容容量阈值
else if (oldThr > 0) { newCap = oldThr; }
// 其他情况
else {
// 赋默认值
newCap = DEFAULT_INITIAL_CAPACITY;
newThr = (int) (DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
}
// 新扩容容量阈值未赋值,1.=新容量 * 扩容因子 2.无法扩容
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;
// j位置数据存在
if ((e = oldTab[j]) != null) {
oldTab[j] = null;
// 不是链表结构,不存在hash冲突
if (e.next == null)
// 计算新hashcode位置并赋值 - 11111 新增前置位随机0/1
{ newTab[e.hash & (newCap - 1)] = e; }
// 是红黑树结构
else if (e instanceof TreeNode) { ((TreeNode<K, V>) e).split(this, newTab, j, oldCap); }
// 是链表结构, 分为两组存储 新标记位0/1
else {
// & oldCap = 0
Node<K, V> loHead = null, loTail = null;
// & oldCap != 0
Node<K, V> hiHead = null, hiTail = null;
Node<K, V> next;
do {
next = e.next;
// 新标记位 = 0
if ((e.hash & oldCap) == 0) {
if (loTail == null) { loHead = e; } else { loTail.next = e; }
loTail = e;
} else {
// 新标记位 != 0
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;
}