2013-12-16 16 views
1

我遇到了JAVA地圖的問題。我在地圖中輸入一個對象作爲鍵。然後我修改鍵,地圖不再將該對象視爲地圖的關鍵。即使對象內的鍵已被相應地修改。Java修改地圖內的關鍵對象

我正在與來自StanfordNLP的對象CoreLabel一起工作,但它適用於我想的一般情況。

Map <CoreLabel, String> myMap = new HashMap... 
CoreLabel key = someCreatedCoreLabel 
myMap.put(key, someString) 
myMap.get(key) != null ----> TRUE 
key.setValue("someValue"); 
myMap.get(key) != null ----> FALSE 

我希望我已經夠清楚了。問題是爲什麼最後的陳述是錯誤的?我不是一個非常有經驗的程序員,但我期望它是真實的。可能與CoreLabel對象有關?

我是否.equals()仍然成立,它實際上

for(CoreLabel token: myMap.keySet()) { 
    if(key.equals(token)) 
     System.out.println("OK"); 
} 
+1

當然,對象將是平等的。不同的是修改對象的哈希碼和對象所在的相應桶(取決於值是否改變了哈希碼) –

+0

好吧,我明白,非常感謝。任何解決這個問題?有沒有辦法重新哈希? – Altober

+1

重新哈希'HashMap'的唯一方法是添加比當前容量更多的元素。這將迫使它重新計算哈希值。你真的不應該這樣做。 –

回答

3

的問題是,在修改鍵值,現在最關鍵的哈希碼也發生了變化。 A HashMap將首先使用密鑰的哈希碼來確定它是否存在。修改後的哈希碼在地圖上不存在,所以它甚至沒有嘗試使用equals方法的步驟。這就是爲什麼當他們在HashMap中時更換關鍵物體是一個壞主意。

7

這在Map的Javadoc危險,不可能明確記載的工作:

注意:如果使用可變對象作爲map的key很大,一定要小心。如果對象的值以影響等於比較的方式更改,而對象是地圖中的關鍵字,則不會指定地圖的行爲。這種禁令的一個特例是,地圖不允許自己作爲關鍵字。雖然地圖可以包含自身作爲值是允許的,但建議您非常小心:equals和hashCode方法在這樣的地圖上不再被很好地定義。