【发布时间】:2017-09-18 11:49:54
【问题描述】:
情况
我需要覆盖equals(),并且建议我还使用相同的字段覆盖hashCode() 方法。然后,当我在看一组时,它只包含一个对象,我得到了令人沮丧的结果
set.contains(object)
=> false
同时
set.stream().findFirst().get().equals(object)
=> true
我现在明白了,这是由于在将 object 添加到 set 之后对其进行了更改,这再次更改了其 hashCode。 contains 然后看错了键,找不到object。
我对实现的要求是
- 需要可变字段才能正确实现
equals() - 在基于哈希的
Collections或Maps中安全地使用这些对象,例如HashSet,即使它们很容易发生变化。
这与约定相冲突
-
equals()和hashCode()应使用相同的字段以避免意外(如本文所述:https://stackoverflow.com/a/22827702)。
问题
仅使用equals() 中使用的字段子集而不是使用全部来计算hashCode() 是否有任何危险?
更具体地说,这意味着:equals() 使用对象的多个字段,而 hashCode() 仅使用那些在 equals() 中使用且不可变。
我认为这应该没问题,因为
- contract 已满:相等的对象将产生相同的 hashCode,而相同的 hashCode 并不一定意味着对象相同。
- 对象的 hashCode 保持不变,即使对象受到更改,因此会在更改前后的
HashSet中找到。
帮助我理解我的问题但不知道如何解决的相关帖子:What issues should be considered when overriding equals and hashCode in Java? 和 Different fields for equals and hashcode
【问题讨论】:
标签: java overriding equals hashcode contract