1.8
put方法详解:
1. 哈希函数
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
如果key == null, hash值 为0
否则,取key的hashCode,设为h, h ^h>>>16 , 让高位也参与运算
2. 定位 桶 的位置
tab[i = (n - 1) & hash]
3. 添加时 两种情况
1) 当前桶 不存在 元素
直接添加
2) 当前桶 已经存在 元素
取出 元素 p,判断是否是相同的元素
p.hash == hash && p.key == key
如果是相同元素,则 p.value = value
如果不是相同元素,则继续查找
如果找到最后一位,还没有找到相同的元素,则将新节点加入到最后位置
3)扩容或树化
>=7 && < 64, 则扩容
>= 64 ,则树化
static final int TREEIFY_THRESHOLD = 8;
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
static final int MIN_TREEIFY_CAPACITY = 64;
// 扩容
if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
resize();
// 树化
else if ((e = tab[index = (n - 1) & hash]) != null) {
TreeNode<K,V> hd = null, tl = null;
do {
TreeNode<K,V> p = replacementTreeNode(e, null);
if (tl == null)
hd = p;
else {
p.prev = tl;
tl.next = p;
}
tl = p;
} while ((e = e.next) != null);
if ((tab[index] = hd) != null)
hd.treeify(tab);
}
4) 扩容
仅对逻辑点进行概述,不涉及代码解释
第一点:
设置 阀值 ,可能会初始化 容量
第二点:
用新的容量,创建一个新的哈希表
第三点:
遍历 旧哈希表 所有桶位,对每个桶位的 元素 迁移到新的哈希表中