javacloneeffective-java

Example for Effective Java where clone() returns a shallow copy


In Effective Java 3rd edition Joshua Bloch talks about how you should implement clone method in complex objects.

public class SimpleHashtable<K, V> implements Cloneable {
    private Entry<K, V>[] buckets; 
    private int size;

    private static class Entry<K, V> {
        final K key;
        V value;
        Entry<K, V> next;

        Entry(K key, V value, Entry<K, V> next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }

        // Recursively clone the linked list of entries
        Entry<K, V> deepCopy() {
            return new Entry<>(key, value, next == null ? null : next.deepCopy());
        }
    }

    public SimpleHashtable() {
        buckets = new Entry[16]; // Default size
    }

    @Override
    public SimpleHashtable<K, V> clone() {
        try {
            @SuppressWarnings("unchecked")
            SimpleHashtable<K, V> result = (SimpleHashtable<K, V>) super.clone();
            result.buckets = new Entry[buckets.length];
            for (int i = 0; i < buckets.length; i++) {
                result.buckets[i] = buckets[i] != null ? buckets[i].deepCopy() : null;
            }
            return result;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

The Entries in the buckets will reference different objects than the original. However, I think that key and value will be references to the same objects as in the original. What if the cloned hash table modifies a value for a given key, then the modification will be reflected in the original. As a result, we really have a shallow copy.

Am I missing something or is the example incorrect?


Solution

  • The new hashtable is a "deep copy" in that if you modify it (by adding/removing entries) the original won't change.

    Yes, the keys and values are the same objects. You should never modify map keys anyway, because if the hash code changes, the data structure will be invalid. The example is to illustrate cloning a hashtable, not the values too.