2012-07-17 160 views
4

我使用HashSet,我需要修改一個對象的ID,但它改變了哈希碼並破壞了HashSet和hashCode()方法的規則。Java:修改改變哈希碼的ID

什麼是最佳解決方案:從Set中刪除對象並添加具有新ID的對象,或將散列碼(例如在構造函數中生成)保存在Set中的每個對象中,或者有其他解決此問題的方法?

感謝您的幫助。

更新: 我犯了一個錯誤:將哈希碼保存在對象中是非常糟糕的,因爲在這種情況下,相同的對象可能會有不同的哈希碼。

+2

你可以重寫'hashCode',所以它做你想要的? – Starkey 2012-07-17 20:08:08

+1

根據定義,一個ID(entifier)不應該改變給定的對象。爲什麼你讓對象的ID是可變的? – StriplingWarrior 2012-07-17 20:14:49

+0

嗯,當我修改我的ID時,我無法生成相同的哈希碼。 – avrilfanomar 2012-07-17 20:14:55

回答

7

作爲容器的HashSet通過您放入其中的項目的哈希代碼訪問其項目(包含,移除)。哈希碼通常由其實例成員的狀態構建。所以哈希碼隨着對象狀態的操縱而改變。

Object文檔說:「保持對的hashCode()方法,其中指出相等的對象必須具有相同的哈希碼總承包合同」

正如你注意到沒有,如果你改變一個對象的狀態,你保留在HashSet中,該對象不能再被remove方法訪問或被HashMap的contains方法找到。

您所提供的選項有:

  1. 刪除對象,改變它,然後重新添加 - 作品精彩,最簡單的方式,如果一個HashSet是強制性

  2. 保留的價值散列碼'somewhere' - 意思是說,對於不相等的對象,你有相同的散列碼。或者,如果你服從文檔,你可能會遇到兩個對象,它們是相等的並且具有相同的散列碼,但是它們的成員變量不同!這可能會導致不可預知的錯誤。

+0

最後一個選項絕對不正確。實際上,HashSet是使用HashMap實現的。如果更改包含對象的狀態,則HashMaps和HashSets將中斷。 – 2012-07-17 21:03:36

+0

也許是誤會?如果你把一個對象放到一個HashMap中,並且你自己選擇了這個鍵(例如一個int),那麼只要你不改變這個鍵,你可以隨意改變這個對象本身。所以關鍵不是(一定)綁定到對象狀態... – Anytoe 2012-07-17 21:40:08

+0

對。但是,由於OP在將對象添加到HashSet後試圖修改密鑰。如果你的建議是密鑰應該從對象中分離出來,並且對象應該是HashMap的值部分,那麼這並不是真正解決同一個問題。 – 2012-07-18 03:47:38