(JDK源码分析)HashMap之put方法
前面解释了HashMap的一些基础概念,今天来解析下put方法
看看数据结构的实现
![](https://img.haomeiwen.com/i3795642/b770c2c6721db9f4.png)
单链表结构 带 hash 增删改查都有了
看看put方法
![](https://img.haomeiwen.com/i3795642/76a636e8dd1cb881.png)
有一个hash方法打开看看
![](https://img.haomeiwen.com/i3795642/463a7034f52ad18f.png)
这里把高低位异或了,什么目的呢?继续往下看
![](https://img.haomeiwen.com/i3795642/1d24dc0bc0e134cf.png)
看到标记处,i=(n-1)&hash 获取元素在hash表中位置。这里我们来搞一些测试用例。
复习一下位运算
![](https://img.haomeiwen.com/i3795642/dff8b712d81d6130.png)
比如 我的 hashcode 二进制 ,这里n的初始值为16,我们在不对hash值进行任何操作的时候会有什么影响
第一个数字 0000 0000 0000 0001 0000 0000 0000 0000
&
0000 0000 0000 0000 0000 0000 0000 1111
结果一 0000 0000 0000 0000 0000 0000 0000 0000
第二个数字 0000 0000 1000 1001 0000 0000 0000 0000
&
0000 0000 0000 0000 0000 0000 0000 1111
结果二 0000 0000 0000 0000 0000 0000 0000 0000
全是0 那我们就找不到元素的位置了很显然是不合适的,而且 hashcode不同的数字位置上也产生了冲突
加上对hash方法的处理后又会有什么变化呢
hashCode ^ hashCode>>>16
第一个数字 0000 0000 0000 0001 0000 0000 0000 0000
>>>16
= 0000 0000 0000 0000 0000 0000 0000 0001
^
0000 0000 0000 0001 0000 0000 0000 0000
= 0000 0000 0000 0001 0000 0000 0000 0001
&
0000 0000 0000 0000 0000 0000 0000 1111
结果一 0000 0000 0000 0000 0000 0000 0000 0001
第二个数字 0000 0000 1000 1001 0000 0000 0000 0000
>>>16
= 0000 0000 0000 0000 0000 0000 1000 1001
^
0000 0000 1000 1001 0000 0000 0000 0000
= 0000 0000 1000 1001 0000 0000 1000 1001
&
0000 0000 0000 0000 0000 0000 0000 1111
结果二 0000 0000 0000 0000 0000 0000 0000 1001
这个操作不明觉厉 ,高位和低位的异或 巧妙的减少了hash的冲突。(向源码致敬!)
这里else之后
![](https://img.haomeiwen.com/i3795642/ee9df6d3da8e34ba.png)
hashCode如果相同,就开始循环遍历链表中的节点,如果没有找到 用加入到链表,如果链表长度超过8转换为红黑树。(红黑树后面安排)
最后size大于threshold 初始值12时候进行扩容,扩容为原来的2倍
![](https://img.haomeiwen.com/i3795642/03b75fe148185f03.png)
put方法的介绍就到这里,resize方法这篇文章说的可以https://segmentfault.com/a/1190000015812438?utm_source=tag-newest