This is an old question but I think there is something else to mention.
If you just want to create a shallow copy of the map then the option number 3 is the most recommended.
However, if you need to make a copy of a map defined as HashMap<Integer, List<Item>>
but you want the original map to stay the same while you change something in the copy. i.e if you remove something from the List in the copy the List in the original should maintain the value.
I have two solutions for this a deep copy function. Right now Java 8 does not provide a native implementation. We can use Guava or Apache Commons Lang. But we can find a work around creating a method to create new instances using foreach
method or Stream.collect()
method. The former is simple we use a foreach to create a new Instance of the object we want to copy in this case a List<T>
Check the generic function here:
public static <T> HashMap<Integer, List<T>> deepCopy(HashMap<Integer, List<T>> original)
{
HashMap<Integer, List<T>> copy = new HashMap<>();
for (Map.Entry<Integer, List<T>> entry : original.entrySet()) {
copy.put(entry.getKey(), new ArrayList<>(entry.getValue()));
}
return copy;
}
If you don't want to deal with generics then we will use Stream.collect()
. In this case we use the stream to extract the data and we wrapped as a map and create a new instance
public static <T> Map<Integer, List<T>> deepCopyStream(Map<Integer, List<T>> original)
{
return original
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, valueMapper -> new ArrayList<>(valueMapper.getValue())));
}
Note
Please, notice that I didn't use <K,V>
for the generics because this is not a proper deep copy method, that will work with nested clones of each level. This approach is based on the idea that we have a HashMap<Integer, List<Item>>
where the Item
class does not contains attributes that requires cloning.