2012-09-25 75 views
4

根據規範:「如果映射先前包含密鑰的映射,則舊值由指定值替換。」我想知道value.equals(舊值)但value!=舊值的情況。我對規範的閱讀是舊的價值必須被替代。是對的嗎?java.util.Map.put(key,value) - 如果值等於現有值,該怎麼辦?

+1

是。你是對的。 –

+0

它將取代並以這種方式可以「清除」System.properties()值;) – 2012-09-25 17:53:51

+2

javadoc是明確的:新值替換舊值,不管它們是相等還是相同。 – assylias

回答

4

如果新密鑰與現有密鑰匹配,則映射值將被替換,而不管其值如何,例如,即使oldValue.equals(newValue)true

我不認爲我們需要看看源,還是要靠測試代碼:這是從Map.put,我們在哪裏找到的文件明確:

如果映射以前包含了一個映射鍵,舊值被指定值替換。 (當且僅當m.containsKey(k)將返回true時,映射m才被認爲包含關鍵字k的映射。)

+0

這不是問題。問題是:當密鑰已經存在時,該值會發生什麼?這被替換。即使價值是相等的? –

+0

像@assylias,你指出我的推理有缺陷。該語言沒有留下解釋的餘地​​。並且你沒有使用HashMap,這對我很重要,因爲這不是Python或PHP,允許參考實現作爲規範的替代品。儘管如此,爲了保護使用HashMap的答案,這是一個接口事物,而不是實現細節,如果Map實現在這一點上含糊不清,那將是瘋狂的。 – philo

0

是的,你的理解是正確的,如果在map中存在相同的值,它將被替換爲新值。

1

沒有檢查值相等性,僅針對關鍵相等。如果您指定的鍵與已經在地圖中的鍵相匹配,則該對象將被替換爲相等。

如果一個值先前與密鑰相關聯,則該值將由put方法返回。以下是HashMap<K,V>的源代碼片段:

for (Entry<K,V> e = table[i]; e != null; e = e.next) { 
    Object k; 
    if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 
     V oldValue = e.value; 
     e.value = value; 
     e.recordAccess(this); 
     return oldValue; 
    } 
} 
1

是的,沒錯。一個簡單的測試會告訴你:

Integer a = new Integer(1); 
Integer b = new Integer(1); 
Map<String, Integer> map = new HashMap<String, Integer>(); 
map.put("key", a); 
map.put("key", b); 
System.out.println("Value is b : " + (map.get("key") == b)); 
+1

但是你真的只是測試一個實現,對吧? – philo

+2

不可以。文檔中明確指出:「將指定值與此映射中的指定鍵相關聯」。如果有些情況下這些值實際上與密鑰不相關,那麼文檔就會說明它。 –

0

我相信你是對的。你可以用這樣的代碼來檢查它:

Map<String, String> strsMap = new HashMap<String, String>(); 
String myString1 = new String("mystring"); 
String myString2 = new String("mystring"); 
strsMap.put("str", myString1); 
System.out.println(myString1 == strsMap.put("str", myString2)); 
System.out.println(myString2 == strsMap.get("str"); 
+1

「Map」的其他實現呢?通過舉例證明不是一個證明。 –

+0

該文檔明確指出這是預期的行爲,如果該鍵的值存在,它將被替換,並且舊值將被返回。但爲了完整性,上面的代碼爲'HashMap','Hashtable','TreeMap'和'WeakHashMap'打印相同的東西,這是直接的實現。其他實現(在文檔頂部(http://docs.oracle.com/javase/6/docs/api/java/util/Map.html))可以擴展這些實現之一或使用組合/代表團。 'EnumMap'和'IdentityHashMap'也有這種行爲。我會說這很具體。 – Brian

+0

@SteveKuo從文檔:「如果映射先前包含該鍵的映射,則舊值由指定值替換。」並且:「**返回:**與'key'有關的前一個值,如果沒有'key'的映射,則返回'null'」。不這樣做是違反了接口契約,所以你可以期待在所有地圖實現中的這種行爲。 – Brian

相關問題