final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {
### 标签:源码|集合
HashMap.Node<K, V>[] tab;
HashMap.Node<K, V> p;
int n, i;
// 初始化table
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
/**
* hash桶里还没有元素
* 为什么是(n - 1)不是n与hash&运算
* 因为&一边为1或者连续的1时,&运算的结果与&另一边的相等
* 1&0=0 0&1=0 1&1=1
*/
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
// hash桶中已经存在元素了
else {
HashMap.Node<K, V> e;
K k;
// key相同做覆盖操作
if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof HashMap.TreeNode)
e = ((HashMap.TreeNode<K, V>) p).putTreeVal(this, tab, hash, key, value);
else {
// 两种情况退出for循环 1.到了链表的末尾 2.找到了相同的key
for (int binCount = 0; ; ++binCount) {
// 1.到了链表的末尾
if ((e = p.next) == null) {
// 在遍历链表的时候才加入新节点,也就是说新节点在不在遍历的范围内
p.next = newNode(hash, key, value, null);
// 链表长度 = binCount+1(binCount从0开始)+1(新增的节点)
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
//添加第九个元素的时候走到了这里(9个元素hash相同),即链表长度大于8
treeifyBin(tab, hash);
break;
}
// 2.找到了相同的key
if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
// 找到了相同的key put做覆盖操作
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
// 因为size 是从0 开始的,所以++size代表了添加完当前元素后的数量 第一次扩容是在添加第13个元素的时候(不考虑初始化扩容和聊表长度超过8但table.length<64的情况)
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}