图解hashmap的put方法

这一篇文章我利用图解的方法来进行分析。首先看一下网上一个比较好的流程图:
图解hashmap的put方法_第1张图片
带你走进Java集合-HashMap源码-put方法图解实战
实例:按照正常的流程走一下put方法

第一行代码:Mapmap = new HashMap<>();
第二行代码:map.put(null,10);
第三行代码:map.put(“dd”,null);
第四行代码:map.put(null,null);
第五行代码:map.put(“a”,1);
第六行代码:map.put(“c”,2);
第七行代码:map.put(“b”,3);
第八行代码:map.put(“a”,4);
第九行代码:map.put(“d”,5);
第十行代码:map.put(“e”,6);
第十一行代码:map.put(“f”,7);
第十二行代码:map.put(“g”,8);

1.第一行代码执行:实例化一个map集合,从这一篇文章中我们知道,当调用new HashMap()构造函数时,HashMap就做了如下内容:

public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
只做了一件事,就是把加载因子默认成0.75.并没有初始化底层的数组。

2:第二行代码:map.put(null,10),此时key=null,value=10,从上一篇分析put源码中,我们并没有看到如果key==null的话,就会抛出异常,所以记住一点:HashMap允许key为null.

当第一次调用put时,他首先会判断底层数组是否被初始化,如果没有初始化,则先进行初始化,源码如下;

if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
走到这一步的图示如下:图解hashmap的put方法_第2张图片

初始化完成以后,会继续下面的插入逻辑

1)首先算出key=null在数组的下标:i = (n - 1) & hash=(16-1)&hash(null)=0
2)然后把此下标的值赋给变量:p=tab[i]=tab[0]
3)判断p==null,则把(null,10)封装成Node,放到此下标中
经过这一步:图示如下:
图解hashmap的put方法_第3张图片

第三行代码:map.put(“dd”,null),也会经过第二步代码的流程,但是此时底层数组已经被初始化了,所以不再进行初始化,而是直接进行插入:

图解hashmap的put方法_第4张图片

1:首先算出key="dd"在数组的下标:i=(n-1)&hash=(16-1)&hash(“dd”)=0

2:然后把此下标的值赋给p=tab[i]=tab[0]

3:判断p!=null,所以继续下面的逻辑

4:key=null和key="dd"的hash值是相等的,所以接下来判断两者的key是否相等,null!=“dd”,所以继续下面的逻辑。

5:判断是否是红黑树TreeNode,判断不是,所以继续下面逻辑,把(“dd”,null)插到链表的末尾。

第四行代码:map.put(null,null)

图解hashmap的put方法_第5张图片

1:首先算出key=null在数组的下标:i=(n-1)&hash=(16-1)&hash(null)=0

2:然后把此下标的值赋给p=tab[i]=tab[0]

3:判断p!=null,所以继续下面的逻辑

4:key=null已经存在了HashMap中,我们的onlyIfAbsent=false所以覆盖

从前四行代码中我们总结如下:

图解hashmap的put方法_第6张图片

1:第一次调用put()方法时,会对底层数组进行初始化,只会初始化一次

2:HashMap可以为key=null,value=null,在null值上,HashMap并没有做特殊的处理。

其余几行按照上面的步骤,执行完后如下:

图解hashmap的put方法_第7张图片

你可能感兴趣的:(集合)