为了在集合中添加一个对象,是否有必要同时覆盖 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
并且你定义 equals
和 hashCode
基于 name
和 surname
以及具有额外属性的具体子 Class Contact Person
,如 email
,定义新的 equals
和 hashCode
很重要为了你的 Class Contact Person
。如果您的 Concrete Class Contact Person
实现了一个将 email
属性 作为唯一字段的实体,则重新定义 equals
和 hashCode
仅基于 email
就足够了。虽然,基于 name
、surname
和 email
定义新的 equals
和 hashCode
更好。
理解这一点的最简单方法是将哈希码视为 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.
最近一位面试官问我,我有一个 class 覆盖了它的 equals()
方法但没有覆盖我的 hashCode()
方法。
现在是否也有必要覆盖我的 hashCode()
方法。?
如果我不覆盖我的 hashcode 方法会发生什么,将设置保持其独特的 属性 不允许重复。?
问题是关于 Set
的内部实现,我的困惑是如果两个对象 return 不同 hashCode()
,根据我的说法,他们的 equals()
不会进行检查,然后如果两个对象相等,则将违反 Set
的唯一性 属性。
这是真的吗?
您应该始终覆盖两者。它们是合同的一部分。
查看 java 文档并确保您在那里完成了详细信息。 Eclipse 也可以为您生成这些方法。
始终推荐两者。
例如如果你有超级 Class Person
属性 id,
, name
, surname
并且你定义 equals
和 hashCode
基于 name
和 surname
以及具有额外属性的具体子 Class Contact Person
,如 email
,定义新的 equals
和 hashCode
很重要为了你的 Class Contact Person
。如果您的 Concrete Class Contact Person
实现了一个将 email
属性 作为唯一字段的实体,则重新定义 equals
和 hashCode
仅基于 email
就足够了。虽然,基于 name
、surname
和 email
定义新的 equals
和 hashCode
更好。
理解这一点的最简单方法是将哈希码视为 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.