HashMap源码解析

1、如何对源码分析
 首先,确定HashMap的功能,我们知道HashMap为一个以键值对的方式来存储数据的一个对象,所以猜想HashMap的数据结构应该为存储的数据结构
 在我们的数据结构中,我们可以想到的存储数据的结构为有链表,顺序表,数组,树等
2、对于数组来说,java中的ArrayList就实现了,我们可以通过源码进行验证
  
其中的Object[]已经说明该类型的数据结构就是一个数组
对于链表数据结构,java中的LinkedList的底层数据结构就是链表,源码如下:
   
从源码中我们可以看到LinkedList中有两个Node属性,其中一个为first,另外一个为last
3、这时候我们猜测HashMap中是否也是这种结构呢,查看源码验证
        

   
上面的tab为一个数组,而Node结点说明了他也用到了链表结构,所以我们确定了HashMap的数据结构如图
    
这种结构确定了HashMap的数据结构为数组加链表的方式,确定了数据结构了,接下来我们就要往下分析了

4、从put方法开始分析
我们试想一下,如果有了一个(key,value),那么应该怎么存储呢,我们猜想Node中会有这两个属性,查看Node源码:
  
这样我们就确定了三个属性,next起到链表作用,目前我们不知道hash干嘛用的,不用急,我们继续分析

5、先贴出put方法的一部分源码:
  
我们分析,首先声明变量,如果tab为null,则调用了resize方法,猜想该方法为初始化tab,因为只有初始化之后数组才能存储数据,点进去查看源码:
 
从源码中可以看出,确实是初始化操作,对于初始化操作,我们都知道要有初始容量,查看源码可知道,HashMap的初始默认容量为16,加载因子为0.75,而阀值threshold等于16×0.75 = 12,即当数组使用到12个的时候,便进行扩容,所以就需要一个size来记录使用个数

这里先提一下hash的作用,为了保证在初始的情况下,来了一个Node数据,使其公平的选择所在的16个位置,采用hash码和2^n-1的求与运算,以便求出0-15的位置
6、初始化之后,会分为两种情况
      1、当数组中为空的时候,选择一个位置进行存放数据
      2、如果选择的数组位置不为空,比较hash值是否相同和key是否相同,如果相同,执行覆盖操作,否则,那么就比较链表的长度,如果大于等于7,则将链表结构进行转换为红白树结构存储,如果没有那么就采用链表结构往下存储。
      然后判断所使用的数组空间数量,如果大于阀值,那么就执行扩容操作,将数据一个一个复制到新的HashMap中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值