2012-09-25 31 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

相关问题