带你走进Java集合-HashMap源码-put方法图解实战

本文通过图解详细分析了Java HashMap的put方法,从实例出发,逐步解析每个步骤,包括初始化、插入逻辑、碰撞处理以及key为null的情况。文章指出HashMap允许key为null,并在null值上没有特殊处理。最后提到了HashMap的扩容机制resize()的源码分析作为后续内容。
摘要由CSDN通过智能技术生成

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

第一行代码:Map<String,Integer>map = 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;
走到这一步的图示如下:在这里插入图片描述

带你走进Java集合-HashMap源码-put方法图解实战
初始化完成以后,会继续下面的插入逻辑

1)首先算出key=null在数组的下标:i = (n - 1) & hash=(16-1)&hash(null)=0
2)然后把此下标的值赋给变量:p=tab[i]=tab[0]
3)判断p==null,则把(null,10)封装成Node,放到此下标中
经过这一步:图示如下:
在这里插入图片描述
带你走进Java集合-HashMap源码-put方法图解实战
第三行代码:map.put(“dd”,null),也会经过第二步代码的流程,但是此时底层数组已经被初始化了,所以不再进行初始化,而是直接进行插入:
在这里插入图片描述
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)插到链表的末尾。
带你走进Java集合-HashMap源码-put方法图解实战
第四行代码:map.put(null,null)
在这里插入图片描述
1:首先算出key="dd"在数组的下标:i=(n-1)&hash=(16-1)&hash(null)=0
2:然后把此下标的值赋给p=tab[i]=tab[0]
3:判断p!=null,所以继续下面的逻辑
4:key=null已经存在了HashMap中,我们的onlyIfAbsent=false所以覆盖
带你走进Java集合-HashMap源码-put方法图解实战
从前四行代码中我们总结如下:
在这里插入图片描述
1:第一次调用put()方法时,会对底层数组进行初始化,只会初始化一次
2:HashMap可以为key=null,value=null,在null值上,HashMap并没有做特殊的处理。
其余几行按照上面的步骤,执行完后如下:
在这里插入图片描述
带你走进Java集合-HashMap源码-put方法图解实战
从上面的例子我们可以看出,即使HashMap的底层数据结构是数组+链表+红黑树,但是HashMap的hash处理的非常的好,一般用不到红黑树。

如果你对HashMap的put逻辑非常的清楚,是非常好理解的,下一篇文章我会对HashMap的扩容机制resize()进行源码分析。
还有就是这我总结出了一些架构视频资料和互联网公司java程序员面试涉及到的绝大部分面试题和答案做成了文档和架构视频资料还有完整高清的java进阶架构学习思维导图免费分享给大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术资料),希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。
在这里插入图片描述
料领取方式:加群:374308445填写【CSDN 资料】即可免费获取!!!
如果您喜欢本文章,可以点击关注,每天将有更多精彩文章与您分享!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值