2012-06-28 35 views
1

我目前正在比較兩個相同類型的複雜對象,多個字段由自定義對象類型的數據結構組成。假設沒有一個自定義對象覆蓋了方法,如果我比較對象中每個字段的哈希碼,並且它們會變成相同的,那麼我是否有100%的置信度,比較對象的內容是一樣?如果沒有,假設我不能使用任何外部庫,那麼您會推薦哪種方法來比較兩個對象。Java hashCode()方法是對象相等的可靠度量嗎?

回答

8

絕對不是。您應該只有使用hashCode()作爲第一遍 - 如果哈希代碼不同,則可以假定對象不相等。如果哈希碼相同,您應該然後調用equals()檢查完全相等。

想想這樣:只有2 可能的哈希碼。作爲示例,String類型有多少種可能的不同對象?遠不止於此。因此至少有兩個不相等的字符串必須共享相同的哈希碼。

Eric Lippert writes well about hash codes - 誠然從.NET的角度來看,但原理是一樣的。

+0

嗨,所以我必須爲超過70個類字段寫一個equals方法,其中許多是自定義對象的數據結構?沒有別的辦法嗎? – LucasSeveryn

+3

如果兩個要比較的對象只有在所有這70個字段相等的情況下才被認爲是相等的,那麼絕對沒有其他辦法。請注意,IDE等IDE可以爲您自動生成'hashCode'和'equals'方法。 – Jesper

+0

因此,對於小對象,我們不使用哈希碼獲得任何東西? – BlueSky

2

沒有,缺乏hashCode()碰撞僅意味着該對象可能是相同的,這是從來沒有一個保證。

唯一保證是,如果hashCode()值是不同的(和hashCode()/equals()實現是正確的),則該對象將不equal

此外,如果您的自定義類型沒有hashCode()實現,則該值是完全無用爲對象的內容比較,因爲這將是identityHashCode()

0

如果您尚未覆蓋hashCode()方法,則所有對象都不相等。通過覆蓋它,您提供了比較的邏輯。請記住,如果您重寫hashCode(),則絕對應該覆蓋equals()編輯: 當然,仍然可以有碰撞,但如果你沒有覆蓋equal(),你的對象將通過引用進行比較(一個對象等於自己)。

0

通常的JVM實現的Object.hashCode()是回到在一些格式對象的內存地址,所以這在技術上可以使用你想要的東西(因爲沒有兩個對象可以共享相同的地址)。

然而,Object.hashCode()實際規範作任何guarentees並且不應當被用於此目的的任何合理的或寫得好的一段代碼。

我會建議使用的hashCode和equals可用建設者在Apache的公共圖書館,或者,如果你真的不能使用免費的外部庫,只是看看他們的靈感。儘管使用最好的方法完全取決於應用程序域中「平等」的含義。