class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0) {
throw new EmptyStackException();
}
Object result = elements[--size];
elements[size] = null; // 다 쓴 참조 해제
return result;
}
private void ensureCapacity() {
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
}
@Override
public Stack clone() {
try {
Stack result = (Stack) super.clone();
result.elements = elements.clone();
return result;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
class HashTable implements Cloneable {
private Entry[] buckets = ...;
@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 RuntimeException(e);
}
}
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;
}
// 이 엔트리가 가리키는 연결 리스트를 재귀적으로 복사
Entry deepCopy() {
return new Entry(key, value, next == null ? null : next.deepCopy());
}
}
... // 나머지 코드 생략
}
Cloneable을 이미 구현한 클래스를 확장하는 경우가 아니라면 복사 생성자와 복사 팩터리라는 더 나은 객체 복사 방식을 사용하자.
// 복사 생성자
public Yum(Yum yum) {}
// 복사 팩터리
public static Yum newInstance(Yum yum) {}