Effective Java 3장 객체의 생성과 삭제
규칙 12. Comparable 구현을 고려하라
CompareTo
-
compareTo 메서드는, Object 에 구현되지않았으며, Comparable 인터페이스에 있는 유일한 메소드
-
단순 동치검사 외 순서비교가 가능한 메서드임. 거의 모든 자바 플랫폼 라이브러리에 포함된 값 클래스는 해당 인터페이스를 구현한다고 보면 됌.
compareTo 메서드 일반규약
일반적으로 해당 규약을 가지는데, 이는 규칙8의 equals 와 매우 유사함.
-
sgn(x.compareTo(y) == -sgn(y.compareTo(x)))
-
x.compareTo(y) > 0 && y.compareTo(z) > 0 이면, x.compareTo(z) > 0
-
x.compareTo(y) == 0 이면, sgn(x.compareTo(z) == sgn(y.compareTo(z)))
-
x.compareTo(y) == 0 == x.equals(y) 를 만족하기를 권장
일반적으로 한 클래스 내 자연적인 순서가 존재하기만 하면, 규약들을 거의 만족한다고 보면 된다.
이 compareTo 클래스의 규약을 어기는 클래스의 경우, 클래스의 오동작을 야기할 수 있으니 주의해야 한다.
compareTo() 규약을 만족하며 새로운 값 컴포넌트를 추가하기 위해 해당 클래스를 상속하는 방법은 없음.
대신, 새로운 클래스를 만들고 원래의 클래스를 멤버변수로 추가하여 해당 클래스를 볼 수 있는 view 메소드를 만들어주면, 필요 시 클라이언트는 새 클래스의 객체를 원래 클래스 객체로 변환해 사용 가능하다
compareTo 메서드와 equals 의 차이
-
Comparable 인터페이스는 자료형을 인자로 받는 제네릭 인터페이스.
- 따라서, 메서드의 인자 자료형은 컴파일 시간에 정적으로 결정되어 서로 다른 클래스 객체에 대해 비교를 고려할 필요가 없으며, 서로 비교 불가한 클래스가 인자로 넘어왔을 때 ClassCastException 예외가 던져진다.
-
null이 인자로 넘겨질 경우는 NullPointerException 이 던져진다.
compareTo 메서드의 구현
-
보통, 객체 참조 필드는 compareTo 메서드를 재귀적으로 호출해 비교.
-
비교할 필드가 Comparable을 구현하지 않고 있거나, 특이한 순서를 이용해야 하는 경우에는 Comparator 를 명시적으로 사용가능하다.
- 직접 구현
- 이미 있는 Comparator 사용가능
public final class CaseInsensitiveString implements Comparable<CaseInsensitiveString>{ public int compareTo(CaseInsensitiveString cis){ return String.CASE_INSENSITIVE_ORDER.compare(s, cis.s); } //.. }
-
비교필드 값의 차이를 반환하는 경우, 비교할 필드가 음수가 아닐 때만 사용가능하며, 필드값 최소치와 최대치의 차가 Integer.MAX_VALUE(2^31-1) 이하인 경우에만 사용가능함.
- 해당 부호비트가 있는 32비트 정수 안에 부호비트가 있는 임의의 32비트 정수 두 개의 차를 온전히 담을 수 없어 일반규약 1, 2 를 위반하게 됌.
'공부 > JAVA' 카테고리의 다른 글
이펙티브 자바 4장 규칙13. 클래스와 멤버의 접근권한은 최소화하라 (0) | 2021.03.14 |
---|---|
[Spring] JSP 한글깨짐 수정 (0) | 2021.03.13 |
이펙티브 자바 3장 규칙 11. clone을 재정의할 때는 신중하라 (0) | 2021.02.17 |
이펙티브 자바 3장 규칙 10. toString은 항상 재정의하라 (0) | 2021.02.17 |
이펙티브 자바 3장 규칙 9. equals를 재정의할 때는 반드시 hashCode도 재정의하라 (0) | 2021.02.17 |
댓글