如何在 java 中克隆或创建地图的新副本

How to clone or create a new copy of Map in java

Map<String, WriteToFileColumnsModel> temp = new ConcurrentHashMap<>(inputMap);
temp.keySet().removeAll(targetMap.keySet());
targetMap.putAll(temp);

targetMap = new ConcurrentHashMap<>(inputMap);

targetMap.putAll(inputMap);

inputMap.forEach(targetMap::putIfAbsent);

for (Map.Entry<String, WriteToFileColumnsModel> entry : inputMap.entrySet()) {
        targetMap.put(entry.getKey(), entry.getValue());
}

我在Stack Over Flow上查看了所有相关问题,并尝试了以上可能的方法。当我执行上述任何一种方式时,都不会创建新实例。当我更改 targetMap 时,inputMap 也会更改。

如有任何帮助,我们将不胜感激。提前致谢:)

您混淆了改变地图和改变地图中的对象

首先:很少需要这样做。复杂的对象,如任何称为 Model 的对象,很少应该被复制。直接传递地图可能更好, 编写一个包装器 class 可以更好地控制如何访问或修改其数据。

您需要深拷贝,这意味着映射中的 classes - StringWriteToFileColumnsModel - 需要支持它们自己的克隆操作。实际上,这是一个半谎言 - String 是不可变的,所以使用浅拷贝很好,因为它永远不会改变。

作为一个更简单的例子,考虑 class

class Person {
    public String name; // can be altered
}

还有一个

List<Person> people = new ArrayList<>();
people.add(new Person("Bob"));

然后你尝试复制它

List<Person> otherPeople = new ArrayList<>(people);

并改变一个...

people.get(0).name = "Sue";

然后得到另一个...

System.out.println(otherPeople.get(0).name); // prints "Sue"

这是您在副本中遇到的问题。

假设支持,您需要单独复制每个 WriteToFileColumnsModel。您可能必须为地图中的每个项目手动执行此操作(或使用一些 Java 8 bullcrap)。

对我来说,您的大部分解决方案都应该有效。但是,我认为最直接的方法是:

Map<String, WriteToFileColumnsModel> targetMap = new ConcurrentHashMap<>(inputMap);

我认为还有另一个问题:您正在更改作为值存储在地图中的对象。由于两个映射指向相同的对象,因此您可以同时更改两个映射的值对象。