2013-11-26 63 views
8

對於散列映射關鍵字來說,是不可變對象(除String之外的其他包裝類等)嗎?不可變對象和散列映射關鍵字

有人可以解釋一下嗎?

+1

不要擔心這一點。 – Maroun

+4

這是不是很清楚你想要什麼。你有特別的擔憂嗎?使用* mutable *對象作爲鍵肯定是一個壞主意 - 至少如果它們能夠以影響哈希碼的方式進行變異。 –

+0

你試圖用什麼來實現? –

回答

6

如果不可變,對象的散列碼不會改變,它允許緩存不同鍵的散列碼,這使得整個檢索過程非常快。 對於可變對象,hashCode()可能依賴於可能發生變化的字段,如果發生這種情況,由於hashCode()返回不同的值,您將無法在HashMap中找到該鍵(及其值)。

0

如果你的對象是不可變的,並且正確地實現了hashcode/equals,你可以很好地將它們用作hashmap中的鍵。

1

是的,因爲它是不可改變的。

讓我們假設我有一個類

MyKey key = new MyKey("shreyansh"); //assume hashCode=1234 
myHashMap.put(key, "value"); 

// Below code will change the key hashCode() and equals() 
// but it's location is not changed. 
key.setName("jogi"); //assume new hashCode=7890 

//below will return null, because HashMap will try to look for key 
//in the same index as it was stored but since key is mutated, 
//there will be no match and it will return null. 
myHashMap.get(new MyKey("shreyansh")); 

這裏同時訪問,使用鍵 「Shreyansh」 它將返回nulll

7

您可以在這裏找到答案:How HashMap works in Java

String,Integer和其他包裝類是HashMap鍵的自然候選者,而String也是最常用的鍵,因爲String是不可變的並且是final,並且覆蓋equals和hashcod e()方法。其他包裝類也共享類似的屬性。不可變性是必需的,以防止用於計算hashCode()的字段上的更改,因爲如果key對象在插入和檢索期間返回不同的hashCode,將無法從HashMap獲取對象。不變性是最好的,因爲它提供了其他優點,如線程安全性。如果只通過最終確定某些字段可以保持hashCode相同,那麼您也可以這樣做。由於equals()和hashCode()方法在從HashMap中檢索value對象時使用,因此重要的是key對象會正確地覆蓋這些方法並跟隨聯繫。如果不相等的對象返回不同的哈希碼比碰撞的機率更小,隨後提高HashMap的性能。

也有另一種堆棧的討論:Why are immutable objects in hashmaps so effective

兩個散列碼和equals方法在看跌的使用和獲得的HashMap的方法。您需要確保在將其與關鍵對象放在一起後,始終可以從地圖中獲取值對象。不管你是否改變關鍵物體。但不可變對象足以實現這一目標。

+0

'如果你可以讓你的hashCode保持相同,只需要使某些字段最終,那麼你也是這樣的。「這是否意味着如果一個鍵是可變的,但它的散列碼不依賴於可變屬性並保持不變,那麼這個可變對象可以是一個好的散列映射關鍵字? –

+0

我想你也需要保持你的平等。否則,在您更改equals方法的值後,如果使用該鍵再次輸入條目,它將不會替換舊值。這不是預期的。 – Jacky

+0

@aLearner如果您查看HashMap的源代碼,這對您會有好處。 – Jacky