为什么hashMap频繁扩容可以减少hash碰撞?

首先我们要知道,hash碰撞是怎么产生的。我这里给大家列举一下。

HashMap 通过散列函数将键映射到哈希表的桶中。如果两个不同的键映射到同一个桶中,则发生哈希碰撞。

当哈希表的负载因子(元素数量/桶数量)增加时,哈希碰撞的概率也会增加,这会导致性能下降。为了避免这种情况,当负载因子超过某个阈值时,HashMap 会自动进行扩容,即创建一个新的更大的哈希表,并将所有元素重新散列到新的桶中。

通过频繁扩容,可以使每个桶中的元素数量保持在一个较低的水平,从而减少哈希碰撞的概率。这是因为扩容会增加桶的数量,从而使负载因子减小。在新的哈希表中,每个桶包含的元素数量更少,因此哈希碰撞的概率更小。

因此,频繁扩容可以使 HashMap 的性能更加稳定,避免因为哈希碰撞导致的性能下降。但是,过于频繁的扩容也会导致性能下降,因为扩容需要重新散列所有元素,这需要花费一定的时间和计算资源。因此,需要在性能和内存使用之间进行平衡,选择合适的扩容阈值和增长因子。

大家看了这段话是不是会产生和我一样的疑问:
比如一个键在hash表的某一个桶中,就算hash表扩容了,桶变多了。但是其他的键如果根据hash函数算出来的键和原先键一样,不还是会找到这个桶吗?
这个问题我也帮大家找到了答案

在 HashMap 扩容时,虽然桶的数量增加了,但每个键的散列值仍然是根据旧的散列函数计算的,并且使用旧的散列函数确定的桶索引仍然会保持不变。因此,如果一个键的散列值不变,那么它在哈希表中的桶位置也不会改变。

但是,当哈希表扩容时,桶的数量增加,因此每个桶中的键值对数量应该会减少,这将有助于减少哈希碰撞的概率。同时,扩容操作还会重新散列所有的键值对,这意味着每个键的散列值可能会重新映射到一个新的桶中,从而进一步减少哈希碰撞的概率。

总之,虽然桶的数量增加了,但是每个键的散列值和它在哈希表中的桶位置仍然保持不变,但通过重新散列键值对和增加桶的数量,扩容可以帮助减少哈希碰撞的概率。

看到这里是不是还没有搞清楚,为什么扩容会减少hash冲突,既然hashcode是相同的,重新分配难道不是还在一个桶中吗?那后续进来的数据不还是在这个桶中吗?
这里就要搞清楚一个很重要的知识点,那就是哈希码对桶的数量取模

虽然两个对象的哈希码在扩容之前相等,并且它们在哈希表中被分配到同一个桶中,但是在扩容时,这两个对象可能会被重新分配到不同的桶中,原因有以下两点:

哈希表的容量会增加,这意味着分配键值对到桶的策略也可能会发生变化。在扩容之前,如果桶的数量比较少,那么相同哈希码的键值对可能会被分配到同一个桶中。但是,当扩容后桶的数量增加时,相同哈希码的键值对可能会被重新分配到不同的桶中。

在HashMap进行扩容时,会对哈希码进行重新计算。新的哈希码通常不同于旧的哈希码,因为在重新计算哈希码时通常使用了新的位移和异或等操作。因此,即使原来的哈希码相等,扩容后的哈希码也可能会不同。

综上所述,在HashMap进行扩容时,两个相同哈希码的键值对可能会被重新分配到不同的桶中,因此,在编写使用HashMap的程序时,不应该依赖于键值对在桶中的顺序,而是应该依赖于HashMap提供的键值对查找机制。

这段要表达的意思是:相同hash码的键,分配到桶中的位置,还要参考hashmap的长度,长度不同,之前分配到相同桶中的数据,可能会分配到不同的桶中

当HashMap进行扩容时,容量会发生变化,因此相同哈希码的键值对可能会被重新分配到不同的桶中。

在HashMap中,哈希码是通过对键的hashCode()方法计算得到的,其值域是整数范围内的任意值。根据哈希码的值,HashMap会将键值对分配到不同的桶中。在桶的数量较少时,相同哈希码的键值对可能会被分配到同一个桶中。但是,在HashMap进行扩容时,桶的数量会增加,相同哈希码的键值对可能会被重新分配到不同的桶中,这取决于新的容量和哈希码计算方法。因此,扩容会影响到HashMap中键值对在桶中的分布情况,甚至可能会导致相同哈希码的键值对被分配到不同的桶中。

那是不是可以这么理解,hashmap长度不变的情况下,相同的hashcode的键,一定会分配到同一个桶?

是的,如果HashMap的长度不变,且相同哈希码的键值对在同一时间被放入HashMap中,那么它们一定会被放入同一个桶中。

当HashMap进行哈希计算时,它会将键的哈希码对桶的数量取模,以确定键值对在HashMap中应该放置在哪个桶中。在HashMap中,每个桶存储着一个链表或红黑树,所有哈希值相同的键值对都会存储在这个链表或红黑树中。

如果HashMap的长度不变,那么桶的数量不会发生变化,哈希计算的结果也不会改变。因此,相同哈希码的键值对在HashMap中一定会被分配到同一个桶中,无论是在扩容之前还是之后。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值