Comparable 인터페이스는 compareTo 메서드만을 정의하고 있다.
equals 와 compareTo 의 다른점
단순 동치성 비교 뿐만 아니라 순서까지 비교 가능하다.
제네릭하다.
Comparable 구현의 장점
정렬, 검색, 극단값 계산 등 수많은 제네릭 알고리즘과 컬렉션의 힘을 누릴 수 있다.
compareTo 메서드의 일반 규약
해당 객체가 주어진 객체보다 작으면 음의 정수, 같으면 0, 크면 양의 정수를 반환한다.
비교할 수 없는 타입의 객체가 주어지면 ClassCastException을 던진다.
x.compareTo(y) * y.compareTo(x) < 0 => 대칭성
x.compareTo(y) > 0 && y.compareTo(z) > 0 이면 x.compareTo(z) > 0 이다 => 추이성
x.compareTo(y) == 0 이면 x.compareTo(z) * y.compareTo(z) > 0 이다 => 반사성
권고. (x.compareTo(y) == 0) == (x.equals(y)) 이다.
위 3가지 대칭성, 추이성, 반사성은 equals 의 일반 규약과 비슷하고, 따라서 하위 클래스에서 필드를 추가하면 똑같은 문제를 겪게 된다.
따라서 equals 와 같이 컴포지션을 활용해 해결할 수 있다.
또, 권고 사항은 지키는 것이 좋다. 어느 라이브러리는 "같다" 를 equals == true 로 사용하고, 어느 라이브러리는 compare == true 로 사용하기 때문
구현 방법
equals 와 거의 동일하되, 같음이 아닌 순서를 비교해야한다. 또, 입력 값의 타입이 정해져 있어 null 만 체크해주면 충분하다
순서 비교는 자바에서 제공하는 비교자(Comparator)를 사용하거나 직접 만들어 사용한다.
일반 값 비교에는 <, > 과 같은 비교 연산자를 직접 사용하지 말고 타입의 compare 정적 메서드를 활용하자.
자바에서 제공하느 비교자는 일반 값, 박싱 타입 객체 뿐만 아니라 일반 객체까지도 compareTo 를 쉽게 정의할 수 있게 도와준다.