put方法

进入put方法,根据对象得hash方法的hash值和自身无符号向右移动16位之后的异或取得的一个hash值作为hash
image.png

  • 先进行扩容 resize()方法
    • 调用位置
      • map第一次put值得之后进入

image.png

  1. - map当前元素得个数已经到达阈值**threshold ** 时候调用

image.png

  1. - 第三在treeifyBin() 方法发现当前得哈希表冲突了并且已经冲突得table得链表中元素得个数到**_TREEIFY_THRESHOLD 8 _**时候会进入treeifyBin tablelength <64时候会进行resize()而不是把链表转化为红黑树
  • 扩容做了什么
    • 扩大容量 增加阈值 第一次扩容 把容量设置为16(Node<K,V>[] newTab = (Node<K,V>[])**new **Node[newCap];threshold = 16*0.75。

image.png
第二次的时候进行扩容会根据老的table.length 和 当前的threshold <<1 也就是直接*2

  1. - 扩容之后需要把旧表中的键值对放入新的表中 (没有仔细看)

经过上面的hash方法得到的hash值 和长度-1进行&(与)操作 把这个key value放到table的这里去
image.png
如果第二次进入put方法 还是上面的key 因为是根据Object的hash方法来计算的,所以必定会有hash值相同的(Integer的hashcode就是值 String 的hashcode的值是 一开始是0 原有的值*31 +char[n])
image.png
当出现冲突了,会进行下面的操作
image.png
(这里先不看树节点的内容)

  1. 如果两个是一个对象(使用equals 判断)那么直接节点直接替换执行下面e!= null的内容 返回老值
  2. 不是同一个对象 ,循环判断 是否有下一个节点,有节点继续判断是否是是同一对象。最后直接放入。