As I understand it, there are a couple of ways (maybe others as well) to create a shallow copy of a Map
in Java:
Map<String, Object> data = new HashMap<String, Object>(); Map<String, Object> shallowCopy; // first way shallowCopy = new HashMap<String, Object>(data); // second way shallowCopy = (Map<String, Object>) ((HashMap<String, Object>) data).clone();
Is one way preferred over the other, and if so, why?
One thing worth mentioning is that the second way gives an "Unchecked Cast" warning. So you have to add @SuppressWarnings("unchecked")
to get around it, which is a little irritating (see below).
@SuppressWarnings("unchecked") public Map<String, Object> getDataAsMap() { // return a shallow copy of the data map return (Map<String, Object>) ((HashMap<String, Object>) data).clone(); }
To create a shallow copy of a Map , pass the existing Map as a parameter to the Map() constructor, e.g. const newMap = new Map(oldMap) . The Map() constructor takes an iterable, such as another Map , and adds the key-value pairs to the new Map .
Shallow Copy/ Cloning Default implementation while using the clone() method a shallow copy of the object is created. It means it creates a new instance and copies all the fields of the object to that new instance where both are referencing to the same memory in heap memory.
HashMap clone() method. The best way to create shallow clone of hashmap is to use it's clone() method. It returns a shallow copy of the map. The keys and values themselves are not cloned; and point to same object in memory as in original map.
It's always better to copy using a copy constructor. clone()
in Java is broken (see SO: How to properly override clone method?).
Josh Bloch on Design - Copy Constructor versus Cloning
If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think
clone
is deeply broken. [...] It's a shame thatCloneable
is broken, but it happens.
Bloch (who by the way, designed and implemented the Collection framework) even went further in saying that he only provides the clone()
method just "because people expect it". He does NOT actually recommend using it at all.
I think the more interesting debate is whether a copy constructor is better than a copy factory, but that's a different discussion altogether.
Neither of the two: the constructor that you are referring to is defined for the HashMap implementation of a Map, (as well as for others) but not for the Map interface itself (for example, consider the Provider implementation of the Map interface: you will not find that constructor).
On the other hand it is not advisable to use the clone()
method, as explained by Josh Bloch.
In respect of the Map interface (and of your question, in which you ask how to copy a Map, not a HashMap), you should use Map#putAll():
Copies all of the mappings from the specified map to this map (optional operation). The effect of this call is equivalent to that of calling put(k, v) on this map once for each mapping from key k to value v in the specified map.
Example:
// HashMap here, but it works for every implementation of the Map interface Map<String, Object> data = new HashMap<String, Object>(); Map<String, Object> shallowCopy = new HashMap<String, Object>(); shallowCopy.putAll(data);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With