If you must implement cloneable interface, please rewrite the clone method correctly.
public class HashTable implements Cloneable {
private Entry[] buckets = null;
private static class Entry {
final Object key;
Object value;
Entry next;
public Entry(Object key, Object value, Entry next) {
this.key = key;
this.value = value;
this.next = next;
}
// This method will cause stack overflow if the list is too long.
// Entry deepCopy() {
// return new Entry(key, value,
// next == null ? null : next.deepCopy());
// }
// Iteratively copy the linked list headed by this Entry
Entry deepCopy() {
Entry result = new Entry(key, value, next);
for (Entry p = result; p.next != null; p = p.next) {
p.next = new Entry(p.next.key, p.next.value, p.next.next);
}
return result;
}
}
@Override
public HashTable clone() {
try {
HashTable result = (HashTable) super.clone();
result.buckets = new Entry[buckets.length];
for (int i = 0; i < buckets.length; i++) {
if (buckets[i] != null) {
result.buckets[i] = buckets[i].deepCopy();
}
return result;
}
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
return null;
}
}
Usually, the copy function is provided by the constructor or factory. A notable exception to this rule is the array, which is easily copied using the clone method.