为什么是java;putAll";无法深度复制映射';什么是价值要素?

为什么是java;putAll";无法深度复制映射';什么是价值要素?,java,dictionary,set,copy,clone,Java,Dictionary,Set,Copy,Clone,我得到了以下代码片段: 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); Ma

我得到了以下代码片段:

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
}
publicstaticvoidmain(字符串[]args){
Map Map=newhashmap();
Set=newhashset();
设置。添加(“用户1”);
设置。添加(“用户2”);
地图放置(“键1”,设置);
Map map2=新的HashMap();
map2.putAll(map);//我希望所有元素都被复制
map.get(“key1”).add(“user3”);//在“map”中添加1个元素
System.out.println(map2.get(“key1”).size();/“map2”受到影响
}
事实上,对map的set元素的修改影响了map2,因此程序将打印“3”而不是“2”

这很奇怪,我想,只要我在新的map2构造中使用“putAll”方法,我认为键和值都应该被深度克隆

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


谢谢

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

您必须循环(或流式)原始
映射
,并创建所有值
的副本:

Map<String, Set<String>> map2 =
    map.entrySet()
       .stream()
       .collect(Collectors.toMap(Map.Entry::getKey,e-> new HashSet<>(e.getValue())));
地图地图2=
map.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,e->newhashset(e.getValue()));
请注意,不需要创建键的副本,因为
String
是不可变的。

另一种方法:

Map<String, Set<String>> map2 = new HashMap<>();
map2.putAll(map);

map2.replaceAll((k, v) -> new HashSet<>(v));
Map map2=newhashmap();
map2.putAll(map);
replaceAll((k,v)->新的HashSet(v));