![](/img/trans.png)
[英]Should hashCode() only use the subset of immutable fields of those used in equals()?
[英]Why all fields used in equals should be also used in hashcode?
@Edit:我正在使用这个库http://jqno.nl/equalsverifier/检查是否正确写入了equals
和hashCode
。
假设我们有这个课程:
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;
}
}
在hashCode
我只在id
字段上转发,因为这会给我很好的,非碰撞的哈希值。 值得注意的是,这种hash
方法符合equals-hashCode
所有规则。 我不想做一些总结哈希的花哨技巧,即:
@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
所以你能解释一下为什么EqualsVerifer
默认需要使用hashCode
方法中equals
方法的所有字段吗?
java.lang.AssertionError: Significant fields: equals relies on subValue, but hashCode does not.
免责声明:我是EqualsVerifier的创建者。
它是默认行为的原因是因为它通常是一种很好的做法,EqualsVerifier希望鼓励其用户遵循良好做法。 您希望hashCode分布尽可能大,以确保在使用基于散列的集合时具有良好的性能。
如果您有充分的理由做其他事情(从您的问题判断,看起来您可能有),您可以通过添加.suppress(Warning.STRICT_HASHCODE)
来禁用此行为。
但我仍然想知道:如果你觉得需要在你的equals方法中包含name
,显然你的id
并不是唯一的。 那么为什么不在hashCode中包含name
? 这并不是说很多额外的工作,特别是因为你可以生成一个从你的IDE,或者干脆使用java.util.Objects.hash(id, name)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.