put方法
进入put方法,根据对象得hash方法的hash值和自身无符号向右移动16位之后的异或取得的一个hash值作为hash
- 先进行扩容 resize()方法
- 调用位置
- map第一次put值得之后进入
- 调用位置
- 当map当前元素得个数已经到达阈值**threshold ** 时候调用
- 第三在treeifyBin() 方法发现当前得哈希表冲突了并且已经冲突得table得链表中元素得个数到**_TREEIFY_THRESHOLD (8) _**时候会进入treeifyBin 当table得length <64时候会进行resize()而不是把链表转化为红黑树
- 扩容做了什么
- 扩大容量 增加阈值 第一次扩容 把容量设置为16(
Node<K,V>[] newTab = (Node<K,V>[])**new **Node[newCap];
) threshold = 16*0.75。
- 扩大容量 增加阈值 第一次扩容 把容量设置为16(
第二次的时候进行扩容会根据老的table.length 和 当前的threshold <<1 也就是直接*2
- 扩容之后需要把旧表中的键值对放入新的表中 (没有仔细看)
经过上面的hash方法得到的hash值 和长度-1进行&(与)操作 把这个key value放到table的这里去
如果第二次进入put方法 还是上面的key 因为是根据Object的hash方法来计算的,所以必定会有hash值相同的(Integer的hashcode就是值 String 的hashcode的值是 一开始是0 原有的值*31 +char[n])
当出现冲突了,会进行下面的操作
(这里先不看树节点的内容)
- 如果两个是一个对象(使用equals 判断)那么直接节点直接替换执行下面e!= null的内容 返回老值
- 不是同一个对象 ,循环判断 是否有下一个节点,有节点继续判断是否是是同一对象。最后直接放入。