HashMap的实现原理

HashMap是一种高效的存储结构,结合了数组和链表的特点。它在内部使用数组存储Entry,每个数组元素可能连接一个链表。当冲突发生时,新元素会被添加到链表头部。当元素数量超过容量的0.75时,HashMap会自动扩容,但这个过程可能导致性能下降。理想的哈希函数会使元素分布均匀,减少链表的形成,从而提高性能。预估HashMap大小可以避免频繁扩容,提升效率。
摘要由CSDN通过智能技术生成

HashMap概述

在数据结构中,物理存储的数据结构只有两种,即数组和链表,其余的如树,队列,栈等数据结构都是在它们的基础上逻辑抽象而来Hashmap实际上是一个“链表散列”的数据结构,是数组和链表的结合体(允许使用null值和null键)
在这里插入图片描述

由图可知,HashMap底层就是一个数组结构,数组中的每一个元素又是一个链表,因此它综合了数组存储和链表存储的优点,通过这种组合实现了查找和增删效率的平衡。其中,最基本的单元是Entry。

HashMap的实现

在这里插入图片描述

当有新的Entry需要加入进来时,根据hash值得到Entry在数组中的位置下标(通过Entry的Key哈希后得到值和table数组的长度位与运算得到数组的下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾(遍历链表,通过equals方法逐个比较key,如果有相同的Key就覆盖,如果没有就追加到链表头部)。

图中红框的Entry构成数组,绿框中的Entry构成链表。

HashMap的扩容

当hashmap中的元素越来越多的时候,碰撞的几率也就越来越高(因为数组的长度是固定的),所以为了提高查询的效率,就要对hashmap的数组进行扩容。

HashMap中数组的默认初始长度是16(源码决定),当数组中有数据的个数超过总数的0.75时,HashMap就会自动扩容(扩大一倍)。一旦扩容,就意味着,旧的HashMap中的Entry全部要迁移到新的HashMap中,也就是rehash(最消耗性能)。扩容的关键在于Entry的key通过什么样的哈希算法重新定位到table中的位置。

自动扩容机制,会导致性能消耗。着启示我们,如果我们已经预知hashmap中元素的个数,那么预设元素的个数能够有效的提高hashmap的性能。比如,我们有1000个元素new HashMap(1000), 但是理论上来讲new HashMap(1024)更合适。 但是new HashMap(1024)还不是更合适的,因为0.75*1000 < 1000, 也就是说为了让0.75 * size > 1000, 我们必须这样new HashMap(2048)才最合适。

总结

HashMap由数组加链表组合体,数组可视为HashMap的哈希桶,链表则是为解决哈希碰撞而存在的,如果定位到的数组位置不含链表(即哈希桶中只有一个Entry),那么对于查找,添加等操作很快,仅需一次寻址即可。;如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,也需遍历链表,然后通过key对象的equals方法逐一比较查找。所以,性能考虑,HashMap中的链表出现越少,性能就会越好。这也暗示着key的哈希值越离散,Entry就会尽可能的均匀分布,出现链表的概率也就越低

参考
1
进阶

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值