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

标签 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);

    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 的副本:

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

请注意,无需创建 key 的副本,因为 String 是不可变的。

关于java - 为什么java "putAll"无法深复制Map的值元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53279994/

相关文章:

java - 找出集合的所有可能的和

list - 如何将列表转换为 LISP 中的集合?

java - 如何检查 <s :message/> has been set in JSF?

java - 通过比较日期从列表中删除项目

python - 从列表字典中获取一组唯一值

c - 将无符号 16 位整数存储到文件的最有效方法

java - 抽象类 protected 方法 junit 测试用例

java - 如何使用Java将合并排序数组int代码格式化为数组字符串代码?

python - python中有没有一种方法可以在循环的单次迭代中循环字典中的多个键值对

scala - 检查 scala 集交集是否为空