【问题标题】:Overriding hashCode() - is this good enough?覆盖 hashCode() - 这是否足够好?
【发布时间】:2011-05-25 10:28:21
【问题描述】:

对于字段完全是原始的类,例如:

class Foo
{
    int a;
    String b;
    boolean c;
    long d;

    boolean equals(Object o)
    {
        if (this == o) return true;
        if (!(o instanceof Foo)) return false;
        Foo other = (Foo) o;
        return a == other.a && b.equals(other.b) && c == other.c && d = other.d;
    }
}

这是写hashCode() 的合理“足够好”的方式吗?

boolean hashCode()
{
    return (b + a + c + d).hashCode();
}

也就是说,我用equals() 使用的相同字段构造了一个String,然后只使用String#hashCode()

编辑:我更新了我的问题,加入了long 字段。 longhashCode() 中应该如何处理?就让它溢出int

【问题讨论】:

  • 虽然效率不高,但应该可以正常工作,因为任何两个具有所有相同内部值的实例都将具有相同的哈希码。
  • 它将正常工作我不知道它的性能问题,但它肯定会工作。如果您想更进一步,请阅读:ibm.com/developerworks/java/library/j-jtp05273.html
  • 只要用commons-lang's HashCodeBuilder就不用担心这种事情了
  • @Spoon:感谢您的评论,尽管我认为这与手头的问题并不完全相关
  • @SpoonBender:你说得很好,但是由于 Matt 只是一个消费者,并且不涉及 Java 规范,所以在这个问题的上下文中它真的无关紧要,除非它会以某种方式更改他问题的“正确”答案。他是否应该根据 HashCode 不应该与 Object 类相关联的知识以某种方式对 Java 代码进行不同的编程?

标签: java equals hashcode


【解决方案1】:

您的哈希码确实满足如果两个对象相等,则它们的哈希码必须相等的属性。所以,这样就“足够好”了。然而,在哈希码中创建冲突是相当简单的,这会降低基于哈希的数据结构的性能。

我会稍微不同地实现它:

public int hashCode() {
    return a * 13 + b.hashCode() * 23 + (c? 31: 7);
}

您应该查看Objectdocumentation for the hashCode() method。它列出了哈希码必须满足的条件。

【讨论】:

  • 我了解equals()hashCode() 的合同。我正在寻找的是一种最小的努力,白痴,没有惊喜的方式来履行合同。您的代码似乎足够合理。你能解释乘以素数的原因吗?另外,我更新了我的问题:如何处理long 字段?
  • @Matt - “最小的努力,”白痴抵抗“路径是使用你的 IDE 来生成方法。例如,Netbeans 为我的一个类生成:int hash = 5; hash = 37 * hash + (int) (this.id ^ (this.id >>> 32)); return hash;
  • @Coronatus:嗯,好点。我忘了Alt + Shift + S (Eclipse)
  • @Matt,原因是给不同位置的数字不同的值。示例:您的对象有int aint b。如果您只是简单地将两个数字相加,哈希码将在 (a=5, b=2 和 a=2, b=5) 的情况下发生冲突。如果将a 乘以一个数字,将b 乘以另一个数字。这些案例不再冲突。
  • @Matt,也许这会有所帮助。 stackoverflow.com/questions/3613102/…
【解决方案2】:

这完全取决于您的数据会是什么样子。在大多数情况下,这将是一个好方法。如果你经常有b 以数字结尾,那么你会得到一些不相等对象的重复代码,正如 JacobM 的回答所示。如果您提前知道 b 在末尾几乎不会有数字值,那么这是一个合理的哈希算法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 2013-06-02
    • 1970-01-01
    • 2013-11-11
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多