HashMap的底层实现原理

HashMap的底层实现原理


一、HashMap的底层实现原理

HashMap 在 JDK1.8 之前的实现方式:数组+链表
JDK1.8之后的实现方式:数组+链表+红黑树

原理:

当你 new 一个 HashMap() 的时候,它底层并没有创建数组。
/
只有当你首次调用 put() 方法时,底层就会创建一个长度为16的数组
/
用数组容量大小乘以加载因子得到一个阈值,一旦数组中存储的元素个数超过该阈值就会进行扩容,通过 rehash() 方法将数组容量增加到原来的两倍,在做扩容的时候会生成一个新的数组,原来的所有数据需要重新计算哈希码值重新分配到新的数组,所以扩容的操作非常消耗性能。

不同的对象算出来的数组下标是相同的这样就会产生 hash 冲突


二、为什么加载因子设置为0.75,初始化临界值是12?

默认的数组大小为16,加载因子为0.75

0.75是对空间和时间效率的一种平衡选择。
/
如果负载因子小一些比如是0.4,那么初始长度16*0.4=6,数组占满6个空间就进行扩容,很多空间可能元素很少甚至没有元素,会造成大量的空间被浪。
/
如果负载因子大一些比如是0.9,这样会导致扩容之前查找元素的效率非常低。
/
oadfactory设置为0.75是经过多重计算检验得到的可靠值,可以最大程度的减少rehash的次数,避免过多的性能消耗。


三、HashMap的判断机制

当链表长度超过8的时候,此时会继续判断哈希表的长度是否小于64。
/
如果小于64,会扩容,如果大于等于64,就会将链表转换为红黑树,提高查询的效率。
/
当红黑树节点小于等于6时又会退化为链表。


四、map.put实现原理

首先通过k的hashCode()方法得出哈希值,通过哈希算法转为数组下标。
/
如果数组下标位置没有元素,就直接添加元素。如果下标对应位置上有链表的话,就会拿k跟链表上所有的k进行equals比较,如果都返回false,就将新元素追加到链表的尾部。
/
如果其中有一个equals返回true,就会将这个节点的value覆盖


五、map.get实现原理

首先通过k的hashCode()方法得出哈希值,通过哈希算法转为数组下标。
/
如果数组下标位置没有元素,就直接返回null。如果下标位置上有链表的话,就会拿k跟链表上所有的k进行equals比较,如果都返回false,就直接返回null。
/
如果有一个返回true,就返回这个节点的value值。

  • 4
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值