How to copy HashMap (not shallow copy) in Java
This does need iteration unfortunately. But it's pretty trivial with Java 8 streams:
mapCopy = map.entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey(), e -> List.copyOf(e.getValue())))
You're right that a shallow copy won't meet your requirements. It will have copies of the List
s from your original map, but those List
s will refer to the same List
objects, so that a modification to a List
from one HashMap
will appear in the corresponding List
from the other HashMap
.
There is no deep copying supplied for a HashMap
in Java, so you will still have to loop through all of the entries and put
them in the new HashMap
. But you should also make a copy of the List
each time also. Something like this:
public static HashMap<Integer, List<MySpecialClass>> copy(
HashMap<Integer, List<MySpecialClass>> original)
{
HashMap<Integer, List<MySpecialClass>> copy = new HashMap<Integer, List<MySpecialClass>>();
for (Map.Entry<Integer, List<MySpecialClass>> entry : original.entrySet())
{
copy.put(entry.getKey(),
// Or whatever List implementation you'd like here.
new ArrayList<MySpecialClass>(entry.getValue()));
}
return copy;
}
If you want to modify your individual MySpecialClass
objects, and have the changes not be reflected in the List
s of your copied HashMap
, then you will need to make new copies of them too.
Serialize to json and deserialize afterwards:
Map<String, Object> originalMap = new HashMap<>();
String json = new Gson().toJson(originalMap);
Map<String, Object> mapCopy = new Gson().fromJson(
json, new TypeToken<Map<String, Object>>() {}.getType());
For special classes you might need to write a custom deserializer.
Just use Apache Commons Lang - SerializationUtils.clone();
Something like these:
Map<String, List<MySpecialClass>> originalMap = new HashMap();
HashMap<String, List<MySpecialClass>> deepCopy = SerializationUtils.clone(new HashMap<>(originalMap));
Also make sure MySpecialClass implements Serializable interface.
public class MySpecialClass implements Serializable{}