2014-11-24 84 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理智的價值,你會使用不同的策略,讓你的對象的哈希碼會更好。

相關問題