HashMap keySet更改未反映在map中

Ada*_*ała 2 java hashmap

我试图迭代HashMap并重写一些元素到另一个地图,但我有以下问题:

@Test
public void test() {
    Map<SubClass, String> map = new HashMap<SubClass,String>();
    Map<SubClass, String> anotherMap = new HashMap<SubClass,String>();
    map.put(new SubClass(), "10");

    for(SubClass i : map.keySet()) {
        System.out.println(i); // initial (because toString is implemented)
        System.out.println(map.get(i)); // 10
        // here it's ok...

        i.name="another";

        System.out.println(i); // another
        System.out.println(map.get(i)); // null!
        // but here it occurs that  map.get(i) returns null!

        anotherMap.put(i, map.get(i));
    }
    for(SubClass i : anotherMap.keySet()) {
        System.out.println(i); // another
        System.out.println(map.get(i)); // null!
    }
}
// SubClass has String name; and hashCode and equals implemented
Run Code Online (Sandbox Code Playgroud)

根据javadoc:

java.util.Map.keySet()

返回此映射中包含的键的Set视图.该集由地图支持,因此对地图的更改将反映在集中,反之亦然.如果在对集合进行迭代时修改了映射(除了通过迭代器自己的remove操作),迭代的结果是未定义的.该集支持元素删除,它通过Iterator.remove,Set.remove,removeAll,retainAll和clear操作从地图中删除相应的映射.它不支持add或addAll操作.

它说"地图的变化反映在集合中,反之亦然".那么为什么它以这种方式表现最重要:如何克服它以使两个映射仅包含已修改的键和非空值?

更新:我的朋友在java 1.5.0.19上做了这个测试(我有1.7.0_03,同样发生在1.5.0_21)并得到了正确的输出:

initial
10
another
10
Run Code Online (Sandbox Code Playgroud)

UPDATE2:哦,他没有实现hashCode/equals,所以第一次更新是无关紧要的

Dev*_*ler 5

你正在修改密钥,而不是地图.无法Map<K,V>检测到您已更改其中的对象.要使地图"看到"您需要调用的remove(originalKey)更改,请更改密钥,然后调用put(modifiedKey,object).

修改地图将是一个呼叫clear,put,putAll,或remove.