Why java "putAll" cannot deep copy Map's value elements?

Hind Forsum :

I got this code snippet:

public static void main(String[] args){
    Map<String, Set<String>> map = new HashMap<>();
    Set<String> set = new HashSet<>();
    set.add("user1");
    set.add("user2");
    map.put("key1", set);

    Map<String, Set<String>> map2 = new HashMap<>();
    map2.putAll(map);// I expect all elements are copied

    map.get("key1").add("user3");// add 1 element in "map"
    System.out.println(map2.get("key1").size()); // "map2" was affected
}

In fact the modification of map's set element affected map2, so the program prints "3" instead of "2"

This is weird, I expect that, as long as I used "putAll" method for the new map2 construction, I think both key and value should be deeply cloned?

How to fix my program and make sure map2 is completed divided from map, while copying all elements from map?

Thanks

Eran :

putAll copies references of the keys and values. It does not make copies of the instances referenced by those references.

You'll have to loop (or stream) over the original Map and create copies of all the value Sets:

Map<String, Set<String>> map2 =
    map.entrySet()
       .stream()
       .collect(Collectors.toMap(Map.Entry::getKey,e-> new HashSet<>(e.getValue())));

Note that there's no need to create copies of the keys, since String is immutable.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=113351&siteId=1