[英]Why all fields used in equals should be also used in hashcode?
@Edit: I'm using this library http://jqno.nl/equalsverifier/ to check if equals
and hashCode
are written properly. @Edit:我正在使用这个库http://jqno.nl/equalsverifier/检查是否正确写入了
equals
和hashCode
。
Let's say we have this class: 假设我们有这个课程:
final class Why {
private final int id;
private final String name;
Why(final int id, final String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (!(o instanceof Why)) return false;
final Why why = (Why) o;
if (id != why.id) return false;
return name != null ? name.equals(why.name) : why.name == null;
}
@Override
public int hashCode() {
return id;
}
}
In hashCode
I'm relaying only on id
field, because this will give me pretty good, non colliding hashes. 在
hashCode
我只在id
字段上转发,因为这会给我很好的,非碰撞的哈希值。 Worth noticing is this hash
method comply with all rules for equals-hashCode
. 值得注意的是,这种
hash
方法符合equals-hashCode
所有规则。 I don't want do some fancy tricks with summing hashes, ie this: 我不想做一些总结哈希的花哨技巧,即:
@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
So could you explain me why EqualsVerifer
by default demand using all fields from equals
method in hashCode
method? 所以你能解释一下为什么
EqualsVerifer
默认需要使用hashCode
方法中equals
方法的所有字段吗?
java.lang.AssertionError: Significant fields: equals relies on subValue, but hashCode does not.
Disclaimer: I'm the creator of EqualsVerifier. 免责声明:我是EqualsVerifier的创建者。
The reason why it's the default behaviour, is because it's generally a good practice, and EqualsVerifier wants to encourage its users to follow good practices. 它是默认行为的原因是因为它通常是一种很好的做法,EqualsVerifier希望鼓励其用户遵循良好做法。 You want your hashCode distribution to be as large as possible, to ensure good performance when using hash-based collections.
您希望hashCode分布尽可能大,以确保在使用基于散列的集合时具有良好的性能。
If you have a good reason to do something else (and judging from your question, it seems like you may have one), you can always disable this behaviour by adding .suppress(Warning.STRICT_HASHCODE)
. 如果您有充分的理由做其他事情(从您的问题判断,看起来您可能有),您可以通过添加
.suppress(Warning.STRICT_HASHCODE)
来禁用此行为。
But I still wonder: if you feel the need to include name
in your equals method, apparently your id
is not unique. 但我仍然想知道:如果你觉得需要在你的equals方法中包含
name
,显然你的id
并不是唯一的。 Why then not also include name
in hashCode? 那么为什么不在hashCode中包含
name
? It's not that much extra work, especially since you can generate one from your IDE, or simply use java.util.Objects.hash(id, name)
. 这并不是说很多额外的工作,特别是因为你可以生成一个从你的IDE,或者干脆使用
java.util.Objects.hash(id, name)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.