Equal object = Equal Hashcode结果,java

时间:2012-01-01 05:17:06

标签: java hashcode

如果我有一个具有坚实,有意义的equals()方法但缺少补充hashCode()方法的对象(即bean),那么“最坏情况”后果(这里的真实场景)是什么?方法?似乎大多数API使用equals()compareTo()方法来维护集合。我想知道hashCode()什么时候最重要?

3 个答案:

答案 0 :(得分:6)

最糟糕的后果是哈希表不起作用。例如,假设你有一个像这样的简单类:

public class StringWrapper {
    private String value;
    ...
    public boolean equals(Object other) {
        // two objects are equal if their respective values are equal ... using `equals`.
    }
    // No hashcode override.
}

这里我们有一个类,我们有一个类不服从equals / hashcode契约的必需不变量之一。具体来说,两个实例cal相等,但具有不同的哈希码。

当您将此类的两个不同实例添加到HashSet时,可能以不同哈希链中的集合中的两个实例结束。从集合中删除对象时,会出现类似的异常,测试集合是否包含对象,等等。

(请注意,你可能会很幸运,尽管有不同的哈希码,但两个实例最终会在同一个哈希链上。但是当一些其他无关的对象被添加到哈希表时,你的运气会改变,导致它自动调整大小.resize可能会导致具有不同哈希码的条目被重新分配到不同的哈希链。)


  

所以我想知道...哈希码什么时候最重要?

这一点很重要。

或者换句话说,当您100%确定地知道该类的实例从未将在哈希表中使用时,它只是不重要。 (而且我不知道你怎么知道这一点,除非你删除了所有课程的副本。这使得整个问题没有实际意义!)


<强>更新

@supercat提到了你不能写一个像样的哈希码的情况。

如果有一个很好的理由你不能写出一个不太合适的hashcode()方法,我主张覆盖它来抛出UnsupportedOperationException或其他一些方法。这样,如果有人试图将实例放入哈希表中,而不是神秘的性能黑洞,那么你会遇到快速失败。 (我不建议返回一个常量哈希码。)

有一个相关的场景,您可能会这样做:当对象固有可变时,并且您希望避免在改变哈希键以使其哈希码发生更改时发生的错误。 / p>

答案 1 :(得分:1)

如果你要关注其中任何一个,你真的,真的应该(需要)实现/覆盖两者。有关详细信息,请参阅Why do I need to override the equals and hashCode methods in Java?,包括如果未通过正确的相关实现实现这些功能,可能会发生什么。

此外,从another answer那里:

  

您必须覆盖覆盖equals()的每个类中的hashCode()。   如果不这样做将导致违反总承包合同   对于Object.hashCode(),它将阻止您的类运行   正确地与所有基于散列的集合一起使用,包括   HashMap,HashSet和Hashtable。

     来自Effective Java的

,来自Joshua Bloch

答案 2 :(得分:0)

此方法返回调用此方法的对象的哈希码值。此方法将哈希码值作为整数返回,并且支持基于哈希的集合类(如Hashtable,HashMap,HashSet等)的优势。必须在覆盖equals方法的每个类中重写此方法。

reference