Shallow copy of a Map in Java

dcp picture dcp · Mar 1, 2010 · Viewed 71.1k times · Source

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

Answer

polygenelubricants picture polygenelubricants · Mar 1, 2010

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 that Cloneable 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.