

新闻资讯
哈希游戏| 哈希游戏平台| 哈希游戏APP哈希游戏- 哈希游戏平台- 哈希游戏官方网站

把它赋值给成员变量threshold表示超过这个值就需要扩容,创建一个容量是16的Node数组,然后赋值给成员变量table,此时调用返回到putVal方法n=16, 此时计算 (n-1) & hash计算出下标值i,判断tab[i]是否等于null,首次添加指定是null,那就新创建一个对象Node,把hash值赋值给成员变量hash,key,value同样赋值,next指向null。 然后tab[i] =Node对象,修改次数成员变量modCount加1,size加1判断是否大于上面提到的threshold,如果大于就调用扩容方法,这里先暂且不分析扩容逻辑,就这样首次调用put方法逻辑 就分析完成了。
接着分析第二次添加的时候,假如此时发生了冲突,即p = tab[i = (n - 1) & hash]) != null,此时p的值是发生冲突时之前已经存在的值,此时分三种情况判断, 判断要添加的hash是否等于冲突的hash值并且key是否相等,如果相等,说明两个对象是同一个对象,把p的值赋值给临时变量e,如果e不为空,先保留老的oldValue值, 把之前的value值赋值为要添加的value,即覆盖已经存在的value值,返回老的value值。
如果也不是红黑树对象,走到else语句,这里首先是一个死循环for,for循环里面也有两个逻辑,如果冲突元素的next节点不等于null, 此时e=p.next,判断e元素的hash值是否等于要添加的元素hash,e元素的key是否等于要添加的元素key,如果相等跳出for循环,后续还是把链表的值替换为 要添加的value值,如果hash或者key不相等把p=e,此时又判断p.next是否等于空,如果为空,说明已经遍历到链表的结尾,此时p.next=新创建元素,此处有个判断逻辑是 if (binCount = TREEIFY_THRESHOLD - 1) treeifyBin(tab, hash); 说明链表长度大于8了调用treeifyBin方法,这个方法又判断数组的长度是否大于64,如果大于转换为红黑树,如果小于就扩容,关于红黑树的逻辑这里还是先不介绍了,感兴趣的可以自己去看看。 到此为止put的源码就分析完成了。
如果条件成立first变量就是要找的元素,判断first的hash值与key计算的hash值是否相等并且first的key是否等于传入的key或者比较两者的equals值是否相等,如果都相等返回first,然后拿到里面的value属性返回。 如果不相等说明发生了hash冲突,把first的next赋值给变量e,判断first是否是红黑树,如果是调用getTreeNode获取,如果不是说明是链表结构,进入一个do while循环,判断e的hash值是否等于key的hash值并且 e的key是否等于key或者比较两者的equals值是否相等,如果不相等就一直获取当前元素的next节点直到相等为止返回元素的value值。
这块的逻辑主要是处理链表桶(非红黑树)的情况,它的主要逻辑是对旧桶中的链表进行重新分配,将节点拆分到新的newTab数组中不同的桶位置。 loHead / loTail:低位链表的头尾指针,hiHead / hiTail:高位链表的头尾指针,这段代码的目的就是将旧链表拆分成两个部分:一个是低位链表(index = j):e.hash & oldCap == 0; 一个是高位链表(index = j + oldCap):e.hash & oldCap != 0,下面一步步进行分析。