静态变量
// 序列号版本UID编号 , 用于序列化private static final long serialVersionUID = 362498820763181265L;// 默认初始容量 2^4 = 16 , 必须是2的倍数static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16// 最大容量 = 2^30static final int MAXIMUM_CAPACITY = 1 << 30;// 默认扩容因子 = 0.75fstatic final float DEFAULT_LOAD_FACTOR = 0.75f;// 默认链表转换红黑树阈值 = 8static final int TREEIFY_THRESHOLD = 8;// 默认由红黑树转换链表的阈值 = 6static 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;// modCounttransient 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 / lengthint 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/1else {// & oldCap = 0Node<K, V> loHead = null, loTail = null;// & oldCap != 0Node<K, V> hiHead = null, hiTail = null;Node<K, V> next;do {next = e.next;// 新标记位 = 0if ((e.hash & oldCap) == 0) {if (loTail == null) { loHead = e; } else { loTail.next = e; }loTail = e;} else {// 新标记位 != 0if (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;}
