一、HashMap的实现原理
HashMap的实现原理图
HashMap实现原理:
HashMap是当你放一个元素(put一个元素),它就根据你的key来锁定你的这个key在哪个桶上;假设你给了一个key,它发现你的可以在上图的第二个桶上,这时候它就看在这个桶上面有没有元素,如果桶里面有元素,它就将你放在桶里面的最后一个元素的next的位置;如果桶里面没有元素,那么它就将你作为桶里面的第一个元素。那么当你在put一个元素,它就又会将你放在一个桶上去,这样的话就可以均匀分布了。但是我们均匀分布的前提是,我们这个取模函数的计算方式,如果计算方式不太好,会出现我们有的桶放的多,有的桶放得少。甚至假如当你有10个桶,元素又特别特别多,如果均匀分布还好,但是如果不是均匀分布的话,会出现有的桶特别长。所以我们HashMap实现最重要的就是我们每个桶里面的元素分布均匀。HashMap的作用就是平衡我们桶的元素和桶里面元素的个数。我们可以一直往HashMap里面put元素,你并不知道它可以put多少元素,当你加入的元素越来越多的时候就会打破这个平衡,这时候我们的内存占用率以及检索都不能达到要求的时候(桶达到某个值、桶里面的链表超过某个值),HashMap内部就会将上面这个结构变成树,树的访问效率极高但是它的维护成本也是极高的。
二、深入源码
1.HashMap中各种默认值(重要)
(1)HashMap最大桶量(MAXIMUM_CAPACITY)为:1<<30(2的30次方)
(2)HashMap的默认因子是:0.75f
(3)树化的阈值(链表值)是:8
(4)最小的树化的容量:64
从这里我们可以看出:当我们的桶的数量超过64,每个桶里面链表的数量超过8的时候,桶会继续保留但是会将链表树化为红黑树。(AVL树——平衡二叉树)
5.HashMap中的各种方法
(1)put方法
对于上面key的值有两种情况,有key=null和key!=null的情况,不等于null的情况比较复杂一些,是通过异或运算得到的。
(2)构造方法
1)无参构造
在HashMap的无参构造里面:
默认容量(初始化容量)=16;(并且是延迟加载)
阈值=12;
因子:0.75
如果我们桶的数量大于64以及链表数量超过8(就是每个桶里面的链表的数量)我们HashMap内部结构就会树化,并且这个树是红黑树。
注意:
(1)对于我们一般使用默认的构造方法就够了,不要轻易的改变默认的容量和负载因子;
但是如果想要改的话有一个公式:负载因子X容量>元素数量。
(2)我们在设置容量的时候最好设置为2的多少次方。
6.HashMap的扩容
HashMap的扩容并不是等到装满以后才扩容的,而是在桶的数量大于(0.75X默认桶量)或元素超过某个阈值的时候进行扩容的。所以我们的负载因子是我们的扩容策略。
7.HaspMap的树化
桶的个数超过64以及链表的元素超过阈值8就树化。
对于HashMap的源码,我们掌握以上知识就可以了。