我有一个非常简单的类,只有一个字段成员(例如字符串)。可以实现hashCode()
简单地返回fieldMember.hashCode()
吗?或者我应该以某种方式操纵该字段的哈希码?另外,如果我应该操纵它,那是为什么呢?
9 回答
如果 fieldMember 是唯一标识对象的好方法,我会说是的。
Joshua Bloch 在“Effective Java”第 3 章中阐述了如何正确覆盖 equals 和 hashCode 。
乘法、加法或异或不会使其更加独特。从数学上讲,您会将常量函数应用于单个变量,这不会增加变量可能值的数量。
这种技术对于组合多个哈希码并仍然保持相对较小的冲突风险很有用;它与单个哈希码无关。
是的,这很标准。如果类反映了数据库行,我只返回主键。
只有两个真正的要求hashCode
:第一,equals
实例具有相同的哈希码,第二,hashCode
运行速度相当快。第一个要求是实践中最重要的要求;没有它,您可以将某些东西放入集合中,但在那里找不到。第二个只是性能问题。
如果您的字段的哈希码算法满足上述条件,那么它的算法也适用于您的类,如果您的类equals
也仅取决于这些字段是否为equals
.
如果“fieldMember”变量已经实现了“hashCode”函数,那么你可以直接从你的父类中使用它。如果 'fieldMember' 变量是自定义类实例,则必须自己正确实现。阅读java.lang.Object API 文档作为实现“hashCode”的指南。
是的。这是很好的编程习惯。我通常使用:
返回变量^ 1;
通常,除非您将此对象用作 *HashMap 的键或 *HashSet 中的元素,否则不需要覆盖 hashCode()。
正如其他人提到的,您应该遵循 Effective Java 中的建议。如果你重写 hashCode() 方法,你也应该重写 equals() 方法。此外,这两种方法应该是一致的。
为了简化编写好的 equals() 和 hashCode() 方法,我使用Apache Commons Lang 的EqualsBuilder和HashCodeBuilder
以下是示例:
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
User other = (User) o;
return new EqualsBuilder()
.append(this.getUniqueId(), other.getUniqueId())
.isEquals();
}
public int hashCode() {
return new HashCodeBuilder()
.append(this.getUniqueId())
.toHashCode();
}