I am trying to iterate on HashMap and rewrite some of the elements to the other map, but I have following problem:
@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
According to javadoc:
java.util.Map.keySet()Returns a Set view of the keys contained in this map. The set is backed by the map, so changes to the
map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in
progress (except through the iterator’s own remove operation), the results of the iteration are
undefined. The set supports element removal, which removes the corresponding mapping from the map,
via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the
add or addAll operations.
It says “changes to the map are reflected in the set, and vice-versa”. So why does it behave this way and most important: how can I overcome it to make both maps contain only modified key and non-null value?
UPDATE:
My friend did this test on java 1.5.0.19 (I have 1.7.0_03, and the same occurs on 1.5.0_21) and got correct output:
initial
10
another
10
UPDATE2:
Oh, he didn’t implement hashCode/equals, so first update is irrelevant
You’re modifying the key, not the map. There is no way for
Map<K,V>to detect that you have changed the object within it. To make the map “see” the change you will need to callremove(originalKey), change the key, then callput(modifiedKey,object).Modifying the map would be a call to
clear,put,putAll, orremove.