【源码】HashMap如何读取遇到哈希冲突的key的值

在遇到哈希冲突时,有以下几种方法可以采用:线性探测法(开放地址法)、链式寻址法(链式散列)、再hash、公共区域等方法[1]。

在Java中,HashMap采用了链式散列,也就是链式寻址法。通常的说,就是数组+链表。数组的每个元素结构如下:
在这里插入图片描述
当遇到哈希冲突[2]时,会将节点放在数组这个节点所代表的链表的最后。

基本上网上的文章都在说Java的HashMap在遇到哈希冲突时是这么解决的哈希冲突,但是很少有说在get的时候,怎么判断的这个链表里哪个节点是这个key对应的节点。

查看了源码以后,发现在get方法是这样的。
在这里插入图片描述

在这里插入图片描述
如上图所示,个人理解,1里的if判断是判断这个hashmap是否是一个有效的非null的map,并定位到链表所在的头节点,也就是将链表所在的头节点的引用赋值给first;

2里的if是在通过hash值和key来判断这个头节点是否是这个头节点是否是这个key对应的节点。

到了3,就说明头节点并不是它想要的节点,会通过Node的next寻找下一个节点,不停的向下寻找节点,不断的通过比较hash和key来判断是否是想要的节点,直到返回value或者返回null为止。

个人浅见,可能会有谬误,欢迎大神指正!

参考文献:
[1],HashMap如何解决哈希冲突?
[2],什么是哈希冲突?哈希冲突怎么解决?

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HashMap的底层是由一个哈希桶数组组成的。而哈希桶的大小取决于初始化HashMap时指定的初始容量,即bucket数组的大小。比如,如果使用new HashMap(19),那么哈希桶数组的大小将为32,即2^5。 HashMap在第一次进行put操作时才会分配内存并初始化哈希桶数组。当put操作需要添加元素时,HashMap会根据元素的哈希计算它在哈希桶数组中的位置,并将元素放入对应的位置。 HashMap在负载因子达到0.75f时会进行扩容,即当哈希桶数组中的元素个数达到了容量的75%时会自动扩容。扩容过程会重新计算元素在新的哈希桶中的位置,并将元素重新插入。 当两个对象的哈希相同时,会发生哈希冲突或碰撞。这意味着它们会被放置在哈希桶数组的同一个位置上的链表中。在这种情况下,HashMap会从对应位置的链表中遍历查找并比较键的,以获取正确的对象。 重新调整HashMap大小时存在一个问题,即重新哈希。因为在扩容时,HashMap需要重新计算元素的哈希,并将元素插入到新的哈希桶数组中。这个过程会导致性能的损耗,并且可能会导致哈希冲突的增加。 另外得一提的是,HashSet的底层也是用HashMap实现的,它只存储key,其中的val都是Object对象。因此,HashSet也具有哈希桶的特性。您可以通过学习JavaHashMap源码来深入了解哈希桶的实现原理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值