你能在hashCode()方法中返回字段的hashCode()值吗?

2022-09-03 00:12:34

在审查大型代码库时,我经常遇到这样的情况:

@Override
public int hashCode() 
{
    return someFieldValue.hashCode();
}

其中,程序员不是为类生成自己唯一的哈希代码,而是直接从字段值继承哈希代码。我的直觉(也可能是消化问题)告诉我这是错误的,但我不能把我的手指放在上面。这种实现可能会出现什么问题(如果有的话)?


答案 1

如果要基于单个属性对对象进行哈希处理,这很好。

例如,在类中,您可能有一个唯一标识 的 ID 属性,因此 of 可以只是该 ID 的哈希值。PersonPersonhashCode()Person

另外,也与.如果两个对象相等,它们必须具有相同的(相反的对象不必为真 - 两个不相等的对象可能仍具有相同的哈希码)。因此,如果相等性由单个属性(如唯一 ID)确定,则该方法还必须仅使用该单个属性。hashCode()equalshashCodehashCode

这可以在hashCode的JavaDoc中看到:

哈希码的总合约是:

  • 每当在执行 Java 应用程序期间在同一对象上多次调用它时,hashCode 方法必须一致地返回相同的整数,前提是不修改对象的相等比较中使用的任何信息。此整数不必从应用程序的一次执行到同一应用程序的另一次执行保持一致。
  • 如果根据 equals(Object) 方法,两个对象相等,则对两个对象中的每个对象调用 hashCode 方法必须生成相同的整数结果。
  • 如果根据 equals(java.lang.Object) 方法,如果两个对象不相等,则不需要在两个对象的每个对象上调用 hashCode 方法必须生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

答案 2

从技术上讲,您可以从 返回任何一致的数字,甚至是常量值。合约对您的唯一要求是相等的对象必须返回相同的哈希代码:hashCode

如果根据 equals(Object) 方法,两个对象相等,则在两个对象中的每个对象上调用该方法必须生成相同的整数结果。hashCode

从理论上讲,如果所有对象都返回,比如说,零,则合约正式得到满足。但是,这完全没用。hashCodehashCode

真正的问题是你是否应该这样做。答案取决于您返回的哈希代码字段的唯一程度。为对象的 返回对象的唯一标识符并不罕见。另一方面,如果很大一部分对象具有 的合理值 ,则最好使用不同的策略来制作对象的哈希代码。hashCodehashCodesomeFieldValue