Deep copying a Java Map with values that are Sets
Solution 1
There was some discussion on this here for deep cloning:
It's hard in this situation though as the new map and set need to rebuild themselves. Do you also need to clone the contents of the Set? If so then you could just serialize then de-serialize the whole collection.
Iterating yourself will almost certainly be faster and will let you control how deep the cloning goes. Serializing will be slower but so long as everything in the object tree is serializable it will copy everything in the object tree and maintain things like circular references etc. (For example if you had 2 keys in the map pointing to the same Set object then iterating will split that into 2 sets, serializing will maintain the link).
Solution 2
If you don't want to use external library and just want to copy this specific map you can do:
HashMap<String, HashSet<String>> copy = new HashMap<>();
for(String newKey : oldMap.keySet()){
copy.put(newKey, new HashSet<String>(oldMap.get(newKey)));
}
Where oldMap is the map you are trying to copy. This worked for me.
cole
Updated on June 21, 2022Comments
-
cole almost 2 years
I have a map (
Map<String, Set<String>>
), and want to copy the map to a new map object. However, if I just feed the map to the sayHashMap
constructor (new HashMap<String, Set<String>>(oldMap)
) it won't do a full copy, and only copies the reference to the set, which can be modified and those changes will be reflected in the new map.Is there a more simply way of doing a full copy other than iterating over each key/value pair and creating a new
HashSet
for each set then adding that to the map? -
Tim B over 10 yearsTrue, but at some point in the future there may be something other than Strings in the Set.
-
cole over 10 yearsYes, I need to clone the contents of the set. The google library seems like it could be effective but I'm trying to keep the project as lightweight as possible. Is there any reason that serialization/deserialization would be a better approach then just iterating over the map and creating a new set for each key/value pair?
-
cole over 10 yearsThe set is actually not implementing strings in my particular scenario, just didn't feel like complicating the question with my custom object.
-
Tim B over 10 yearsSometimes simplifying too much obscures the answer, if I had made the "String immutable" assumption it might change things in my answer. See edit for more details on the two approaches.
-
cole over 10 yearsThanks for the answer, I have all the information I need to make the best decision here.
-
Tim B over 10 yearsNo worries. For what it's worth I would probably go down the iteration approach unless I needed to worry about objects being referenced from multiple places.