애매모호한 clone 규약
-
clone 규약
x.clone() != x 반드시 true
x.clone().getClass() == x.getClass() 반드시 true
x.clone().equals(x) true가 아닐 수도 있다.
-
불변 객체라면 다음으로 충분하다.
-
Cloneable 인터페이스를 구현하고, clone 메서드를 재정의한다.
이때 super.clone()을 사용한다.
가변 객체의 clone 구현하는 방법
- 접근 제한자는 public, 변환 타입은 자신의 클래스로 변경.
deepCopy - 배열을 직접 만든 후, 하나씩 배열을 만들어 넣어 준다.
재귀적으로 만드면 stack이 쌓여서 스택오버플로우가 생길 수도 있다.
shallowCopy - 배열 안에 있던 코드를 동일하게 참조하고 있음
가변 객체 clone할 때 주의사항
clone() 안에서 다른 메서드를 호출할 때
- 추상 객체를 구현할 때는 Cloneable 인터페이스를 구현하지 않는 게 좋다.
- synchronized까지 붙여야 정석적인 clone() 메서드 사용 방법
- 생성자를 써서 clone하기
- final을 쓸 수 없다.
clone 대신 권장하는 방법
- "복사 생성자" 또는 변환 생성자, "복사 팩터리" 또는 변환 팩터리
- 생성자를 쓰지 않으며, 모호한 규약, 불핋요한 검사 예외, final 용법 방해 등에서 벗어날 수 있다.
- 또 다른 큰 장점 중 하나로 인터페이스 타입의 인스턴스를 리턴할 수 있다.
- 클라이언트가 복제본의 타입을 결정할 수 있다.
*참고) Josh Bloch on Design, "Copy Constructor"
완벽 공략
- p80. 비검사 예외(UnChecked Exception)였어야 했다는 신호다.
- p81. HashTable과 LinkedList
- p83. deep copy
- p83. 리스트가 길면 스택 오버플로를 일으킬 위험이 있기 때문이다.
- p85. clone 메서드 역시 적절히 동기화해줘야 한다.
- p86. TreeSet
Unchecked Exception
- RuntimeException
- Error를 상속받은 Exception
왜 비검사 예외를 선호하는가?
- 컴파일 에러를 신경 쓰지 않아도 된다.
- try-catch로 감싸거나 메서드 선언부에 선언하지 않아도 된다.
- 검사 예외가 있는 이유 : 클라이언트에게 잡지 않은 예외를 알려줄 수 있기 때문이다.
언제 어떤 예외를 써야하는가?
- 단순히 처리하기 쉽고 편하다는 이유만으로 RuntimeException을 사용하지 말 것.
- 가이드라인 : 클라이언트에게 복구할 수 있는 예외라면 CheckedException을 사용하고, 해당 예외 발생 시 아무것도 할 수 없다면 비검사 예외를 만든다.
TreeSet
AbstractSet을 확장한 정렬된 컬렉션
- 엘라먼트를 추가한 순서는 중요하지 않다.
- 엘리먼트가 지닌 자연적인 순서(natural order)에 따라 정렬한다.
- 오름차순으로 정렬한다.
- 스레드 안전하지 않다.
- 과제) 이진 검색 트리, 레드 블랙 트리 학습
Binary Search Tree
이진 탐색 트리 : 이진트리(각 노드의 자식 노드가 최대 2개인 트리)를 갖는 트리이다.
- 각 노드에 중복되지 않는 키(key)가 있다.
- 루트 노드의 왼쪽 서브 트리는 해당 노드의 키보다 작은 키를 갖는 노드들로 이루어져 있다.
- 루트 노드의 오른쪽 서브 트리는 해당 노드의 키보다 큰 키를 갖는 노드들로 이루어져 있다.
- 좌우 서브 트리도 모두 이진 탐색 트리여야 한다.
출처: https://code-lab1.tistory.com/10 [코드 연구소:티스토리]
Red Black Tree
레드 블랙 트리 : 자가 균형 이진 탐색 트리이다.
- 모든 노드는 빨간색 혹은 검은색이다.
- 루트 노드는 검은색이다.
- 모든 리프 노드(NIL)들은 검은색이다. (NIL : null leaf, 자료를 갖지 않고 트리의 끝을 나타내는 노드)
- 빨간색 노드의 자식은 검은색이다. == No Double Red(빨간색 노드가 연속으로 나올 수 없다)
- 모든 리프 노드에서 Black Depth는 같다. == 리프노드에서 루트 노드까지 가는 경로에서 만나는 검은색 노드의 개수가 같다.
출처: https://code-lab1.tistory.com/62 [코드 연구소:티스토리]
TreeSet은 내부적으로 TreeMap(정렬된 맵)이란 걸 사용한다.