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

Per*_*rry 13 java hashcode

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

@Override
public int hashCode() 
{
    return someFieldValue.hashCode();
}
Run Code Online (Sandbox Code Playgroud)

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

Era*_*ran 16

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

例如,在一Person类,你可能有一个唯一识别的ID属性Person,所以hashCode()Person可以简单地是ID的哈希值.

另外,hashCode()与实施有关equals.如果两个对象相等,它们必须相同hashCode(相反的情况不一定是真的 - 两个不相等的对象可能仍然具有相同的hashCode).因此,如果相等性由单个属性(例如唯一ID)确定,则该hashCode方法也必须仅使用该单个属性.

这可以在hashCode的JavaDoc中看到:

hashCode的一般契约是:

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


das*_*ght 10

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

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

从理论上讲,如果所有对象都返回零hashCode,那么合同就会正式满足.但是,这hashCode完全没用.

真正的问题是你是否应该这样做.答案取决于您要返回的哈希码的字段的唯一性.返回hashCode对象的对象的唯一标识符并不罕见hashCode.另一方面,如果有相当大比例的对象具有合理的值someFieldValue,那么最好使用不同的策略来制作对象的哈希码.