【问题标题】:Hash code collision handling in collison chain冲突链中的哈希码冲突处理
【发布时间】:2016-09-13 12:29:00
【问题描述】:

让我们考虑HashMap,它使用单独的链接来解决哈希码冲突。

如果我有多个条目,其中 hascode 相同,冲突机制会形成所有这些条目的链表链。

现在,让我们考虑一个情况,这样的链表显示为:

(K1,V1,->) (K2,V2, ->) (K7,V7,->) (K9,V9,)

现在一个新的条目进来了,它的哈希码和K7一样,key的值也一样。它会覆盖 K7 的现有值吗?

【问题讨论】:

  • 是的,因为如果哈希码相等并且您正在对冲突列表进行操作,equals() 将启动,即将检查列表中的键是否与新键相等。因此,如果您为等于 K7 的键添加新值,则该值将被替换。 - 顺便说一句,这就是为什么 hashCode() 和 equals() 应该总是一起实现/覆盖的原因。
  • 取决于实现。正如@KevinEsche 所说, List 可以包含重复项,所以它可能没问题。你为什么不试试呢?
  • 这个问题被标记为hashmap。这应该是一个提示。
  • @duffymo 当然有一个具有相同哈希值的所有条目的列表。
  • 在现代HashMap 中甚至还有二叉搜索树。它改善了在具有大量哈希码冲突的不良情况下的行为。

标签: java hashmap hash-collision


【解决方案1】:

【讨论】:

  • 虽然思考 Hashmap 的内部工作原理肯定很有趣;这个问题基本上归结为“如果我两次使用相同的键,hashmap 会覆盖该值”,根据地图合同,答案是肯定的。
  • 满足合约的方式有很多种,其中只有一种是替换哈希冲突链中现有节点的value引用。这个问题在询问实现细节时非常清楚。
【解决方案2】:

hashmap函数public V put(K key, V value)explains关于hash-collision解析的定义。

将指定的值与此映射中的指定键相关联。如果 映射先前包含键的映射,旧值是 更换。

putVal() 的片段,由put() 调用

633             if (p.hash == hash &&
634                 ((k = p.key) == key || (key != null && key.equals(k))))
635                 e = p;
...
652             if (e != null) { // existing mapping for key
653                 V oldValue = e.value;
654                 if (!onlyIfAbsent || oldValue == null)
655                     e.value = value;
656                 afterNodeAccess(e);
657                 return oldValue;
658             }

【讨论】:

  • 感谢大家的回答
猜你喜欢
  • 2013-09-01
  • 2015-04-07
  • 1970-01-01
  • 2017-06-25
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
相关资源
最近更新 更多