Comparable 인터페이스는 객체들을 순서대로 정렬할 수 있도록 한다. 이 인터페이스를 구현하는 클래스는 compareTo 메서드를 오버라이드 해야하며, 이 메서드는 객체 자신과 다른 객체를비교하여 정렬 순서를 결정하는데사용된다.
compareTo 메서드의 일반 규약
1. 호출 결과의 부호는 첫 번째 객체가 두 번째 객체보다 작은지, 같은지, 큰지를 나타낸다.
- compareTo가 반환하는 값이 0보다 작으면, 첫 번째 객체가 두 번째 객체보다 작다는 것을 의미합니다.
- compareTo가 반환하는 값이 0이면, 두 객체는 동일하다는 것을 의미합니다.
- compareTo가 반환하는 값이 0보다 크면, 첫 번째 객체가 두 번째 객체보다 크다는 것을 의미합니다.
2. 두 객체 참조의 순서를 바꿔 비교해도 예상한 결과가 나와야 한다.
- x<y 면 y>x 다
- x==y 면 y==x다
- x>y 면 y<x다
3. 첫 번째가 두 번째보다 크고 두 번째가 세 번째보다 크면, 첫 번째는 세 번째보다 커야한다.
- x>y이고 y>z 면 x>z다
4. 크기가 같은 객체들끼리는 어떤 객체와 비교하더라도 항상 같아야 한다.
5. 두 객체가 compareTo로 0을 반환할 경우 equals 메서드에서 true를 반환해야 한다.
- 그러나 equals가 true를 반환할 경우에 compareTo가 0을 반환할 필요는 없다.( compareTo는 equals보다 더 세밀한 비교를 제공할 수 있음)
compareTo 메서드를 재정의시 관계 연산자 '<'와 '>'를 사용하면 안된다.
이따금 '값의 차'를 기준으로 첫 번째 값이 두 번째 값보다 작으면 음수를, 두 값이 같으면 0을, 첫 번째 값이 크면 양수를 반환하는 compareTo나 comapre 메서드를 마주치는데 이 방식을 사용해서는 안된다. 정수 오버플로나 부동소수점 계산 방식에따른 오류가 발생할 수 있기 때문이다.
해시코드 값의 차를 기준으로 하는 비교자 - 추이성에 위배되므로 권장되지 않음!
static Comparator<Object> hashCodeOrder = new Comparator<>() {
public int compare(Obejct o1, Object o2) {
return o1.hashCode() - o2.hashCode();
}
};
권장되는 정적 compare 메서드를 활용한 비교자 예시
static Comparator<Object> hashCodeOrder = new Comparator<>() {
public int compare(Obejct o1, Object o2) {
return Integer.compare(o1.hashCode(), o2.hashCode());
}
};
비교자 생성 메서드를 활용한 비교자
static Comparator<Object> hashCodeOrder =
Comparator.comparingInt(o -> o.hashCode());
결론 : 순서를 고려해야 하는 값 클래스를 작성한다면 꼭 Comparable 인터페이스를 구현하여, 그 인스턴스들을 쉽게 정렬하고, 검색하고, 비교 기능을 제공하는 컬렉션과 어우러지도록 해야 한다. compareTo 메서드에서 필드의 값을 피교할 때는 박싱된 기본 타입 클래스가 제공하는 '정적 compare 메서드나 Comparator 인터페이스가 제공하는 비교자 생성 메서드를 사용하자.
'이펙티브 자바' 카테고리의 다른 글
[이펙티브 자바] 아이템 16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라 (0) | 2024.03.18 |
---|---|
[이펙티브 자바] 아이템 15. 클래스와 멤버의 접근 권한을 최소화하라 (0) | 2024.03.18 |
[이펙티브 자바] 아이템 13. clone 재정의는 주의해서 진행하라 (3) | 2024.03.14 |
[이펙티브 자바] 아이템 12. toString을 항상 재정의하라 (0) | 2024.03.12 |
[이펙티브 자바] 아이템 11. equals를 재정의하려거든 hashcode도 재정의하라 (0) | 2024.03.12 |