2014-11-24 86 views
13

在审查大量的代码库,我常常遇到的情况是这样的:你可以在hashCode()方法中返回一个字段的hashCode()值吗?

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

其中编程,而不是产生自己独特的哈希码类,简单地从一个场继承的哈希码值。我的直觉(这可能是消化问题)告诉我这是错误的,但我不能把它放在手指上。这种实施可能会产生什么问题?

+0

这实际上是罚款。唯一的要求是两个相等的对象返回相同的散列。这里就是这种情况。 – ortis 2014-11-24 10:12:01

+0

是的,特别是对于不可变对象。例如,java.lang.String就是这样做的。 – user11153 2014-11-24 13:59:10

+1

我发现“继承”是单词的一个不合理的选择,因为Java有一个称为继承的概念,它不涉及这个问题。我会打电话给这个代表团。 – Bryan 2014-11-24 18:13:50

回答

16

这很好,如果你想散列基于单个属性的对象。

例如,在一个Person类,你可能有一个唯一标识Person的ID属性,所以PersonhashCode()可以简单地是ID的哈希值。另外,hashCode()equals的实施有关。如果两个对象相同,它们必须具有相同的hashCode(相反,不一定是正确的 - 两个不相等的对象可能仍然具有相同的hashCode)。因此,如果相等性由单个属性(例如唯一ID)确定,那么hashCode方法也必须仅使用该单一属性。

这可以在hashCode的JavaDoc可以看出:

hashCode的一般合同是:

  • 每当它是Java的执行期间,在同一对象不止一次上调用应用程序中,只要修改了对象的等号比较中使用的信息,hashCode方法就必须始终返回相同的整数。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。
  • 如果两个对象根据equals(Object)方法相等,则对这两个对象中的每个对象调用hashCode方法必须产生相同的整数结果。
  • 根据equals(java.lang.Object)方法,如果两个对象不相等,则不要求对两个对象中的每个对象调用hashCode方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高散列表的性能。
+0

我喜欢那句方式的要求是说,代码知道两个对象都为'hashCode()方法返回不同的值'有权假设任何相等比较会产生'FALSE'。当对象被修改时,可变类对象的哈希代码可以改变*如果*没有关于其哈希代码的缓存信息存在于宇宙中的任何地方。即使使用可变类型,代码通常也可以满足后者的条件,但不幸的是,没有自动化的方法来执行要求或确保符合要求。 – supercat 2014-11-24 19:02:04

2

这是好的,如果你真的想通过这个单一属性唯一地标识你的对象。这是一个article,它解释了什么是对象标识。

Object文档中所述,您的equals()hashCode()需要包含相同的属性,请务必确认。

所以这意味着你应该问自己这个问题:如果只有这个单一属性是相等的,我真的希望这些对象是相等的吗?

最后做一个定制equals()hashcode()实现子类对象时会非常谨慎,如果你想属性添加到对象的身份,你会打破a.equals(b) == b.equals(a)(明白为什么这个失败的事情有关此要求a是超类和b作为子类。

3

hashCode()有去与equals()

如果唯一的财产界定equalness是,例如,一个ID,你要照顾好你的哈希码是等于ID相等时。 完成此操作的最简单方法是取出您的ID的hashCode()

-2

是的,你可以做到这一点从技术上说,你需要的是一个非基本somefieldValue。

+0

你为什么不推荐它? – stuXnet 2014-11-24 10:15:44

+1

这取决于应用程序的,如果你想somefieldValue – prsutar 2014-11-24 10:32:49

+0

不IMO一个有用的答案的散列码。你并没有指出可能出现的问题或需要注意的地方,这个简短答案的很大一部分只是指出了真正的基本语法,如果专门搜索(应该是很容易解决的)对于原语* do *具有哈希码功能,所以这不是一个硬性约束,而是一个小的语法差异)。 – Dukeling 2014-11-24 18:47:35

10

从技术上讲,你可以可以hashCode返回任何一致的数字,即使是一个常数值。唯一requirement the contract places upon you是相等的对象必须返回相同的散列码:

如果两个对象根据equals相等(Object)方法,然后调用在每个两个对象的hashCode方法必须产生相同的整数结果。

理论上,如果所有对象的hashCode都返回0,则合同正式满足。但是,这使得hashCode完全无用。

真正的问题是你是否应该做不做。答案取决于你正在返回的哈希码字段的唯一性。为对象的hashCode返回对象的唯一标识符的hashCode并不罕见。在另一方面,如果对象的显著比例有someFieldValue理智的价值,你会使用不同的策略,让你的对象的哈希码会更好。