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的应用场景

HashMap源码分析

相关推荐