HashMap源码分析
一 HashMap中的底层存储原理
HashMap中的存储:数组+链表/红黑树;
Entry<K,V>[] entry
在 java1.8之前其存储结构为 :数组+链表,到java1.8的时候对其进行了优化,在链表的长度大于8的时候桶的结构将会转换成红黑树,当节点数最少为6的时候,还原为链表。这个数值是为了防止频繁转换结构而影响效率(无非是在 空间和时间之间获取的一个拍比较合适的点而已)
为了防止单链表过长影响效率,Hashmap中还采取了取模算法(长度对hash值取余数(取模算法为了提高效率采用位与运算&)作为数组的索引值以确定元素的存放位置)
HashMap对Hash值冲突解决:当Hash值冲突之后 1.先判断key值是否和冲突的值相等。如相等则进行判断Value值是否相等如不相等进行替换,当key值不等的时候则以单链表的形式存放在一个桶中。
关于负载因子:
负载因子最直接的是影响HashMap中数组扩容的一个比例参数,默认是0.75,例如:当前HashMap中的数组的长度为length,当数组中有0.75*length的元素被沾满的时候就会对数组扩容,另一方面:负载因数影响了Hashmap的查询效率,当负载因数越小,那么数组就会容易触发扩容,数组长度较大,那么hash值关于长度的取模散列排布中hash值冲突的几率较小,链表就会交端,那么查询的效率就会提升。;
但是负载因子小的时候扩容的次数就会增多,对HashMap进行扩容,需要从新计算每个元素的Hash值,从新进行散列排布,这也是非常消耗性能的,所以负载因子太小也会早场put值得效率降低。
二 HashMap之中的源码逻辑导向
1 在HashMap进行实例话的时候:仅仅对HashMap中的负载因子进行了默认赋值0.75.
2 在第一次对HashMap进行put()值得时候对数组的元素进行了初始化 扩容
3 在第二次进行put值得时候会对key的Hash值进行判断是否冲突,若冲突则形成单链表
4 在put值得时候中间会插入一些判断,对数组沾满率的判断,判断是否达到阈值(是否需要扩容),对链表的判断是否需要转换成红黑树
5 其中每一次扩容都是初始化新的更大空间的数组,将老的数组放到新的数组中的过程
三 HashMap的插入和查询效率
插入效率和负载因子成正比
查询效率和负载成反比
四 HashMap的基本业务逻辑
五 HashMap中的疑难点
六 HashMap中的学习点
Hash值得计算
取模算法
链表遍历
final static triansant的应用场景