2013년 10월 17일 목요일

Clone 인터페이스

import java.util.TreeSet;

// 깊은 복사가 가능하도록 Cloneable인터페이스 구현
class Clone implements Cloneable, Comparable<Clone> {
String name;
int age;
public Clone() {
this("", 0);
}
public Clone(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name+"씨(" + age + "세)";
}
// 정렬을 지원하는 클래스를 사용하기 위한 Comparable<Clone>인터페이스 구현
@Override
public int compareTo(Clone o) {
// 정렬기준 : 나이 역순인데 동일한 나이일경우 이름 가나다 역순이다.
if(o.age > age )
return 1;
else if(o.age < age)
return -1;
else
return name.compareTo(o.name) * -1; // * -1하면 내림차순, 안하면 오름차순
}


// Cloneable인터페이스 구현시는 반드시 오버라이드 해주어야 한다.
// 내용은 return super.clone();면된다.
// 이 메소드는 상위에 protected멤버로 만들어져있어 안만들어주면 접근 불가이다.
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}

}
public class CloneTest {
public static void main(String[] args) {
Clone c1 = new Clone("한사람",33);
Clone c2 = c1;
// 출력 결과는 같다. 그렇다면 두개는 따로 존재하는 놈일까? 아님 하나일까?
System.out.println(c1);
System.out.println(c2);
// 하나의 이름만 바꿨다. 과연 하나만 바뀌었을까? 둘다 바뀌었다. 그렇다면 객체는 1개다.
c2.name = "두사람";
System.out.println(c1);
System.out.println(c2);
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());

// 위의 결과는 객체는 1개만 생기고 두개의 변수가 같은 주소를 참조하기때문이다.
// 결국 내용이 아닌 주소만 복사되었다. 얕은복사!!

// 그럼 실제 내용이 복사(깊은복사)되게 하려면 어떻게 해야 할까?
Clone c3 = new Clone();
c3.name = c1.name;
c3.age  = c1.age;
System.out.println(c1);
System.out.println(c3);
c3.name = "딴사람";
System.out.println(c1);
System.out.println(c3);
System.out.println(c1.hashCode());
System.out.println(c3.hashCode());

// 그런데 필드가 아주 많다면 위의 작업은 굉장히 복잡할 것이다.
// 이럴때는 깊은 복사를 지원해주는 cloneable 인터페이스를 구현해주면 된다.
try {
Clone c4 = (Clone)c1.clone();
c4.name = "또다른사람";
System.out.println(c1);
System.out.println(c4);
System.out.println(c1.hashCode());
System.out.println(c4.hashCode());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}

// 정렬 테스트
TreeSet<Clone> set = new TreeSet<>();
set.add(new Clone("한사람",33));
set.add(new Clone("한사람",32));
set.add(new Clone("두사람",32));
set.add(new Clone("세사람",31));
set.add(new Clone("한사람",31));
set.add(new Clone("네사람",31));
System.out.println(set);

}
}

댓글 없음:

댓글 쓰기