为了在集合中添加一个对象,是否有必要同时覆盖 equals 和 hashcode。?

For adding an object in set, is it necessary to override equals and hashcode both.?

最近一位面试官问我,我有一个 class 覆盖了它的 equals() 方法但没有覆盖我的 hashCode() 方法。

现在是否也有必要覆盖我的 hashCode() 方法。?

如果我不覆盖我的 hashcode 方法会发生什么,将设置保持其独特的 属性 不允许重复。?

问题是关于 Set 的内部实现,我的困惑是如果两个对象 return 不同 hashCode(),根据我的说法,他们的 equals() 不会进行检查,然后如果两个对象相等,则将违反 Set 的唯一性 属性。

这是真的吗?

您应该始终覆盖两者。它们是合同的一部分。

查看 java 文档并确保您在那里完成了详细信息。 Eclipse 也可以为您生成这些方法。

始终推荐两者。

例如如果你有超级 Class Person 属性 id,, name, surname 并且你定义 equalshashCode 基于 namesurname 以及具有额外属性的具体子 Class Contact Person,如 email,定义新的 equalshashCode 很重要为了你的 Class Contact Person。如果您的 Concrete Class Contact Person 实现了一个将 email 属性 作为唯一字段的实体,则重新定义 equalshashCode 仅基于 email 就足够了。虽然,基于 namesurnameemail 定义新的 equalshashCode 更好。

理解这一点的最简单方法是将哈希码视为 buckets.When 您将对象存储在集合中,它们根据计算出的哈希码进入这些存储桶。

当您覆盖 equals 时,即一个对象等于另一个对象,因此它们应该落在同一个桶中。

但是情况并非如此,因为您没有覆盖哈希码方法来确保这一点。

因此jvm 会尝试在错误的桶中搜索对象。不会找到它,因此您将有重复项。 (顺便说一句,我的面试也快开始了,真的很害怕!)

具体要看具体Set-implementation, as mentioned by the Collection doc(Collection是Set的超class)

(The Object.hashCode() specification guarantees that two objects with unequal hash codes cannot be equal.) More generally, implementations of the various Collections Framework interfaces are free to take advantage of the specified behavior of underlying Object methods wherever the implementor deems it appropriate.

因此,例如 HashSet (as the name suggests) will use the hash value, other implementations of Set 可能不会 - 并且只能使用 equals()

Object.equals 文档终于给出了一些好的建议:

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.