为什么java"putAll"无法深度复制Map的值元素?

Hin*_*sum 2 java dictionary clone copy set

我得到了这段代码:

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
}
Run Code Online (Sandbox Code Playgroud)

实际上map的set元素的修改会影响map2,所以程序打印"3"而不是"2"

这很奇怪,我希望,只要我使用"putAll"方法进行新的map2构建,我认为密钥和值都应该深入克隆?

如何修复我的程序,并确保map2完成从地图分割,同时从地图复制所有元素?

谢谢

Era*_*ran 7

putAll复制键和值的引用.它不会复制这些引用引用的实例.

您将必须循环(或流)原始Map并创建所有值Set的副本:

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

请注意,不需要创建密钥的副本,因为它String是不可变的.