【问题标题】:When using hashmaps, should hash collisions be avoided or encouraged?使用 hashmap 时,应该避免还是鼓励 hash 冲突?
【发布时间】:2021-03-23 16:44:06
【问题描述】:

如果我正在编写一个Employee 类,它将保存在一些基于哈希的集合中,如 hashmap/hashset。 Employee 对象 int hashcode() 实现是否应该避免或鼓励散列冲突?特别是对于插入和检索的性能

【问题讨论】:

  • 避开它们,碰撞越多,使用速度就越慢。事实上,就像equals 一样,您可以使用所有字段,因此没有“尝试做或不尝试”,只有所有字段
  • 除非您的作业特别要求您编写自己的 hashCode 算法,否则最好使用现有的。例如,Employee.hashCode 可能只是做return this.employeeID.hashCode();return Objects.hash(firstName, lastName, jobTitle);。请记住,它需要基于 equals(Object) 检查的相同属性。
  • 您可以计算equals 使用的属性子集的哈希值;这只是意味着可能在不相等的对象上发生哈希冲突。这是完全合法的。通常这不是一个好主意,但在某些情况下可能是有原因的(例如,性能,在您判断由于省略字段不太可能发生冲突的情况下)。
  • 这能回答你的问题吗? What Exactly is Hash Collision

标签: java hashmap hashset


【解决方案1】:

避免。一个好的散列算法的要点是在可用的散列桶上均匀分布散列对象。

考虑退化的情况:

   int hashCode() { return 0; }

这满足了 hashCode 实现的所有技术要求。它也绝对确保碰撞。结果是所有内容都进入同一个存储桶,并且(在典型实现中)您的哈希映射具有与数组列表相同的性能。

另一方面,在大多数情况下,“少数”冲突不会引起注意。您只是不想在任何一个存储桶中有“太多”条目。

在您的特定情况下,Employee 记录可能具有唯一的“员工 ID”。您可以将其用作 hashCode 的唯一内容。如果 id 已经是一个整数,那就更好了。对于 id 模映射大小相同的情况,您会在映射(而不是 hashCode 结果)中遇到冲突,但无论如何这是不可避免的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 2015-06-14
    • 2018-02-04
    • 2016-03-01
    • 1970-01-01
    • 2010-11-30
    相关资源
    最近更新 更多