Search code examples
javadictionaryhashmapdeep-copy

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());
}

I checked all the related questions on Stack Over Flow and tried the above possible ways. When I do any of the above way, new instance isn't created. When I alter targetMap, inputMap is altered too.

Any help would be appreciated. Thanks in advance :)


Solution

  • You're confusing altering the map with altering the objects in the map.

    First and foremost: I rarely need to do this. Complex objects, like any called Model, rarely should be copied. It may be better to just pass the map around directly, or write a wrapper class that has better control over how its data can be accessed or modified.

    You need a deep copy, which means the classes in the map - String and WriteToFileColumnsModel - need to support their own clone operation. Actually, this is a half-lie - String is immutable so using a shallow copy is fine, since it can never change anyway.

    As a simpler example consider a class

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

    And a

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

    And you try to copy it

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

    And alter one...

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

    And get the other one...

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

    This is the problem you are having in your copy.

    You need to copy each WriteToFileColumnsModel individually, assuming this is supported. You probably will have to manually do this for each item in the map (or use some Java 8 bullcrap).