HashMap 1.8
put
调用putVal方法 putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) ,onlyIfAbsent参数为冲突时是否覆盖原值,此处传false,覆盖原值。
使用hash(key)方法获取第一个参数。如果key为null,该方法返回0,所以可以存null键
putVal
如果第一次调用该方法,先初始化table
将hash和table.length-1进行与运算,获得存储的下标i
如果table中该下标为null,说明该key第一次put且没有产生冲突,直接tab[i] = new Node(hash,key,value,null),最后一个参数为Node链表的next节点
否则,说明hash冲突或者之前put过相同的键
判断table[i]中的第一个Node
p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))) 为true说明put了相同的键,当前put的值和第一个Node key相同
否则判断table[i]中的节点是不是TreeNode红黑树节点 putTreeVal
否则从table[i]中的第二个Node开始遍历
如果遍历过程中Node为空了
说明该key第一次put,为链表当前遍历的节点的下一节点赋值 p.next = newNode(hash, key, value, null);
判断当前是否遍历到第八个链表节点或以上
调用treeifyBin方法
如果当前table.length大于64将链表转为红黑树,
否则扩容table
如果遍历过程中节点的键equals(当前put的键),说明put了相同的键
如果是put了相同的键
替换为新值
返回旧值
// 程序运行至此,说明第一次put此key
modcount++
size++
判断size是否大于扩容阈值
扩容
返回null