为什么java "putAll"不能深拷贝Map的值元素?
Why java "putAll" cannot deep copy Map's value elements?
我得到了这个代码片段:
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
}
实际上修改map的set元素影响了map2,所以程序打印“3”而不是“2”
这很奇怪,我希望只要我使用 "putAll" 方法来构建新的 map2,我认为键和值都应该被深度克隆?
如何修复我的程序并确保 map2 从 map 中分离出来,同时复制 map 中的所有元素?
谢谢
putAll
复制键和值的引用。它不会复制这些引用所引用的实例。
您必须循环(或流式传输)原始 Map
并创建所有值的副本 Set
s:
Map<String, Set<String>> map2 =
map.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,e-> new HashSet<>(e.getValue())));
请注意,不需要创建密钥的副本,因为 String
是不可变的。
另一种方式:
Map<String, Set<String>> map2 = new HashMap<>();
map2.putAll(map);
map2.replaceAll((k, v) -> new HashSet<>(v));
我得到了这个代码片段:
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
}
实际上修改map的set元素影响了map2,所以程序打印“3”而不是“2”
这很奇怪,我希望只要我使用 "putAll" 方法来构建新的 map2,我认为键和值都应该被深度克隆?
如何修复我的程序并确保 map2 从 map 中分离出来,同时复制 map 中的所有元素?
谢谢
putAll
复制键和值的引用。它不会复制这些引用所引用的实例。
您必须循环(或流式传输)原始 Map
并创建所有值的副本 Set
s:
Map<String, Set<String>> map2 =
map.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,e-> new HashSet<>(e.getValue())));
请注意,不需要创建密钥的副本,因为 String
是不可变的。
另一种方式:
Map<String, Set<String>> map2 = new HashMap<>();
map2.putAll(map);
map2.replaceAll((k, v) -> new HashSet<>(v));