@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
方法中的equals
方法的所有字段来解释默认为hashCode
的原因?
java.lang.AssertionError: Significant fields: equals relies on subValue, but hashCode does not.
答案 0 :(得分:2)
免责声明:我是EqualsVerifier的创建者。
它之所以成为默认行为,是因为它通常是一种很好的做法,EqualsVerifier希望鼓励其用户遵循良好做法。您希望hashCode分布尽可能大,以确保在使用基于散列的集合时具有良好的性能。
如果您有充分的理由做其他事情(从您的问题判断,看起来您可能有一个),您可以通过添加.suppress(Warning.STRICT_HASHCODE)
来始终禁用此行为。
但我仍然想知道:如果您觉得需要在等号方法中加入name
,显然您的id
并不是唯一的。那么为什么不在hashCode中包含name
?它不是 额外的工作,特别是因为您可以从IDE生成一个,或者只使用java.util.Objects.hash(id, name)
。