gpt4 book ai didi

java - 为什么在 equals 中使用的所有字段也应该在 hashcode 中使用?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:10:06 24 4
gpt4 key购买 nike

@Edit:我正在使用这个库 http://jqno.nl/equalsverifier/检查equalshashCode是否写对了。

假设我们有这个类:

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)

关于java - 为什么在 equals 中使用的所有字段也应该在 hashcode 中使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47212630/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com