🏠 Comparable 을 구현할지 고려하라
이번 아이템은 Comparable 인터페이스의 메서드인 compareTo 에 대해서 알아보는 챕터이다.
compareTo 메서드는 Object 의 equals 메서드와 달리 순서까지 비교할 수 있으며, 제네릭하다.
때문에 Comparable 을 구현했다는 것은 해당 클래스의 인스턴스들에는 자연적인 순서가 있음을 뜻한다.
사실상 자바 플랫폼 라이브러리의 모든 값 클래스와 열거형 타입은 Comparable 을 구현했다.
알파벳, 숫자, 연대 같이 순서가 명확한 값 클래스를 작성한다면 반드시 Comparable 인터페이스를 구현하자.
🔥 Comparable 의 compareTo 메서드의 규약
Comparable 인터페이스를 구현할 때 따라야하는 compareTo 규약에 대해서 설명한다.
일반적으로 equals 규약과 비슷하다.
두 객체의 순서를 비교한다. 두 객체가 비교할 수 없는 타입이면 ClassCastException 을 던진다.
또한 주어진 객체가 작으면 음의 정수를, 같으면 0을, 크면 양의 정수를 반환한다.
💧 밑에 사용될 예시 sgn 표시는 수학에서 말하는 부호함수를 뜻하며, 값이 음수, 0 , 양수일 때 -1, 0, 1 을 반환한다고 가정한다.
- Comparable 을 구현한 클래스는 모든 x,y 에 대해서 sgn(x.compareTo(y)) == -sgn(x.compareTo(x)) 여야 한다. 즉 두 객체의 참조 순서를 바꿔서 비교해도 예상한 결과가 나와야한다.
- Comparable 을 구현한 클래스는 추이성을 보장해야 한다. 즉 (x.compareTo(y) > 0 && y.compareTo(z) > 0) 이면 x.compareTo(z) > 0 이다.
- Comparable 을 구현한 클래스는 x.compareTo(y) == 0 이면 sgn(x.compareTo(z)) == sgn(y.compareTo(z)) 이다. 즉 크기 가 같은 객체들끼리는 어떤 객체와 비교하더라도 항상 같아야 한다.
- Comparable 을 구현한 클래스는 x.compareTo(y) == (x.equals(y)) 이어야 한다. 즉 동치성 테스트 결과과 equals 의 결과와 같아야 한다는 뜻이다. 그래야 해당 클래스를 정렬된 컬렉션에 넣을 때 해당 컬렉션이 구현한 인터페이스가 정상 동작한다.
- 이 클래스의 순서는 equals 메서드와 일관되지 않다.
equals 메서드가 모든 객체에 대해 전역 동치관계를 부여하지만, compareTo 메서드는 타입이 다른 객체를 신경쓰지 않아도 된다.
그저 다른 타입이 들어오면 ClassCastException 메서드를 던지면 된다.
Comparable 을 구현한 클래스를 확장해 값 컴포넌트를 추가하고 싶다면, 확장하는 대신 독립된 클래스를 만들고 해당 클래스에 원래 클래스 인스턴스를 가리키는 필드를 두자. 그런 다음 내부 인스턴스를 반환하는 "뷰" 메서드를 제공하면 된다.
이렇게 하면 원하는대로 바깥 클래스에 compareTo 메서드를 구현해 넣을 수 있을 뿐더라, 클라이언트는 필요에 따라 바깥 클래스의 인스턴스를 필드 안에 담긴 원래 클래스의 인스턴스로 다룰 수 있다.
🔥 Comparable 의 compareTo 메서드의 작성요령
- 타입을 인수로 받는 제네릭 인터페이스이므로, 컴파일타임에 인수 타입이 결정된다. 때문에 따로 확인하거나 형변환 할 필요가 없다.
- compareTo 메서드는 동치인지 비교하는 것이 아닌 순서를 비교한다. 객체 참조 필드를 비교하려면 compareTo 메서드를 재귀적으로 호출해야한다. Comparable 을 구현하지 않은 필드나 표준이 아닌 순서로 비교해야 한다면 Comparator 를 사용하면 된다.
- 클래스의 핵심 필드가 여러개라면 가장 핵심적인 필드부터 비교해나가자. 비교 결과가 0이 아니라면 거기서 끝이다. 결과를 곧장 반환하자.
'개인 공부 > 스터디' 카테고리의 다른 글
[이펙티브 자바] equals 재정의 (0) | 2023.06.13 |
---|---|
[이펙티브 자바] 상속보다는 컴포지션을 사용하라 (1) | 2023.06.13 |
[데이터 중심 어플리케이션 설계] 설계시 고려사항 (0) | 2023.06.05 |
[이펙티브 자바] 불필요한 객체 생성 (2) | 2023.05.16 |
[이펙티브 자바] Builder (0) | 2023.05.09 |