在审查大量的代码库,我常常遇到的情况是这样的:你可以在hashCode()方法中返回一个字段的hashCode()值吗?
@Override
public int hashCode()
{
return someFieldValue.hashCode();
}
其中编程,而不是产生自己独特的哈希码类,简单地从一个场继承的哈希码值。我的直觉(这可能是消化问题)告诉我这是错误的,但我不能把它放在手指上。这种实施可能会产生什么问题?
在审查大量的代码库,我常常遇到的情况是这样的:你可以在hashCode()方法中返回一个字段的hashCode()值吗?
@Override
public int hashCode()
{
return someFieldValue.hashCode();
}
其中编程,而不是产生自己独特的哈希码类,简单地从一个场继承的哈希码值。我的直觉(这可能是消化问题)告诉我这是错误的,但我不能把它放在手指上。这种实施可能会产生什么问题?
这很好,如果你想散列基于单个属性的对象。
例如,在一个Person
类,你可能有一个唯一标识Person
的ID属性,所以Person
的hashCode()
可以简单地是ID的哈希值。另外,hashCode()
与equals
的实施有关。如果两个对象相同,它们必须具有相同的hashCode
(相反,不一定是正确的 - 两个不相等的对象可能仍然具有相同的hashCode)。因此,如果相等性由单个属性(例如唯一ID)确定,那么hashCode
方法也必须仅使用该单一属性。
这可以在hashCode的JavaDoc可以看出:
hashCode的一般合同是:
- 每当它是Java的执行期间,在同一对象不止一次上调用应用程序中,只要修改了对象的等号比较中使用的信息,hashCode方法就必须始终返回相同的整数。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。
- 如果两个对象根据equals(Object)方法相等,则对这两个对象中的每个对象调用hashCode方法必须产生相同的整数结果。
- 根据equals(java.lang.Object)方法,如果两个对象不相等,则不要求对两个对象中的每个对象调用hashCode方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高散列表的性能。
我喜欢那句方式的要求是说,代码知道两个对象都为'hashCode()方法返回不同的值'有权假设任何相等比较会产生'FALSE'。当对象被修改时,可变类对象的哈希代码可以改变*如果*没有关于其哈希代码的缓存信息存在于宇宙中的任何地方。即使使用可变类型,代码通常也可以满足后者的条件,但不幸的是,没有自动化的方法来执行要求或确保符合要求。 – supercat 2014-11-24 19:02:04
hashCode()
有去与equals()
。
如果唯一的财产界定equalness是,例如,一个ID,你要照顾好你的哈希码是等于ID相等时。 完成此操作的最简单方法是取出您的ID的hashCode()
。
是的,你可以做到这一点从技术上说,你需要的是一个非基本somefieldValue。
从技术上讲,你可以可以从hashCode
返回任何一致的数字,即使是一个常数值。唯一requirement the contract places upon you是相等的对象必须返回相同的散列码:
如果两个对象根据equals相等(Object)方法,然后调用在每个两个对象的
hashCode
方法必须产生相同的整数结果。
理论上,如果所有对象的hashCode
都返回0,则合同正式满足。但是,这使得hashCode
完全无用。
真正的问题是你是否应该做不做。答案取决于你正在返回的哈希码字段的唯一性。为对象的hashCode
返回对象的唯一标识符的hashCode
并不罕见。在另一方面,如果对象的显著比例有someFieldValue
理智的价值,你会使用不同的策略,让你的对象的哈希码会更好。
这实际上是罚款。唯一的要求是两个相等的对象返回相同的散列。这里就是这种情况。 – ortis 2014-11-24 10:12:01
是的,特别是对于不可变对象。例如,java.lang.String就是这样做的。 – user11153 2014-11-24 13:59:10
我发现“继承”是单词的一个不合理的选择,因为Java有一个称为继承的概念,它不涉及这个问题。我会打电话给这个代表团。 – Bryan 2014-11-24 18:13:50