我得到了以下代码片段:
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
}
实际上,对地图set元素的修改会影响map2,因此程序将打印“ 3”而不是“ 2”
这很奇怪,我希望只要在新的map2结构中使用“ putAll”方法,我都认为键和值都应该被深克隆?
如何在复制地图中的所有元素的同时修复程序并确保map2已从map中分割出来?
谢谢
答案 0 :(得分:6)
putAll
复制键和值的引用。它不会复制那些引用所引用的实例。
您必须循环(或流式传输)原始的Map
并创建所有值Set
的副本:
Map<String, Set<String>> map2 =
map.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,e-> new HashSet<>(e.getValue())));
请注意,由于String
是不可变的,因此无需创建密钥的副本。
答案 1 :(得分:1)
Another way:
Map<String, Set<String>> map2 = new HashMap<>();
map2.putAll(map);
map2.replaceAll((k, v) -> new HashSet<>(v));