언어/JAVA

[Effective Java] Comparable을 구현할지 고려하라

2020. 3. 15. 22:16
반응형

아이템 14 : Comparable을 구현할지 고려하라

 

compareTo 메서드의 일반 규약은 equals의 규약과 비슷하다.

  • Comparable을 구현한 클래스는 모든 x,y에 대해 sgn(x.compareTo(y)) == -sgn(y.compareTo(x))여야 한다(따라서 x.compareTo(y)는 y.compareTo(x)가 예외를 던질 때에 한해 예외를 던져야 한다).
  • Comparable을 구현한 클래스는 추이성을 보장해야 한다. 즉, (x.compareTo(y) > 0 && y.compareTo(z) > 0)이면 x.compareTo(z) > 0이다.
  • Comparable을 구현한 클래스는 모든 z에 대한 x.compareTo(y) == 0 이면 sgn(x.compareTo(z)) == sgn(y.compareTo(z))다.
  • 이번 권고가 필수는 아니지만 꼭 지키는게 좋다. (x.compare(y) == 0) == (x.equals(y)) 여야 한다. Comparable을 구현하고 이 권고를 지키지 않는 모든 클래스는 그 사실을 명시해야 한다. 다음과 같이 명시하면 적당할 것이다.

"주의 : 이 클래스의 순서는 equals 메서드와 일관되지 않다."

 

첫 번째 규약은 두 객체 참조의 순서를 바꿔 비교해도 예상한 결과가 나와야 한다는 것이다. 즉, 첫 번째 객체가 두 번째 객체보다 작으면, 두 번째가 첫 번쨰보다 커야 한다. 첫 번째가 두번째와 크기가 같다면, 두 번째는 첫 번째와 같아야 한다. 마지막으로 첫 번째가 두 번째보다 크면, 두 번째는 첫 번쨰보다 작아야 한다.

두 번째 규약은 첫 번째가 두 번째보다 크고 두 번째가 세 번째보다 크면, 첫 번째는 세 번째보다 커야 한다는 뜻이다.

마지막 규약은 크기가 같은 객체들끼리는 어떤 객체와 비교하더라도 항상 같아야 한다는 뜻이다.

 

이상의 세 규약은 compareTo 메서드로 수행하는 동치성 검사도 equals 규약과 똑같이 반사성, 대칭성, 추이성을 충족해야 함을 뜻한다.

 

compareTo의 마지막 규칙은 필수는 아니지만 꼭 지키길 권한다. 마지막 규약은 간단히 말하면 compareTo 메서드로 수행한 동치성 테스트의 결과가 equals와 같아야 한다는 것이다.

 

Effective Java 2판에서는 compareTo 메서드에서 정수 기본 타입 필드를 비교할 때는 관계 연산자인 <와 >를, 실수 기본 타입 필드를 비교할 때는 정적 메서드인 Double.compare와 Float.compare를 사용하라고 권했다. 그런데 자바 7부터는 상황이 변했다. 박싱된 기본 타입 클래스들에 새로 추가된 정적 메서드인 compare를 이용하면 되는 것이다. compareTo 메서드에서 관계 연산자 <와 >를 사용하는 이전 방식은 거추장스럽고 오류를 유발하니, 이제는 추천하지 않는다.

 

핵심 정리

순서를 고려해야 하는 값 클래스를 작성한다면 꼭 Comparable 인터페이스를 구현하여, 그 인스턴스들을 쉽게 정렬하고, 검색하고, 비교 기능을 제공하는 컬렉션과 어우러지도록 해야 한다. compareTo 메서드에서 필드의 값을 비교할 때 <와 > 연산자는 쓰지 말아야 한다. 그 대신 박싱 기본 타입 클래스가 제공하는 정적 compare 메서드나 Comparator 인터페이스가 제공하는 비교자 생성 메서드를 사용하자.

반응형

'언어 > JAVA' 카테고리의 다른 글

[Effective Java] public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라  (0) 2020.03.16
[Effective Java] 클래스와 멤버의 접근 권한을 최소화하라  (0) 2020.03.16
[Effective Java] clone 재정의는 주의해서 진행하라  (0) 2020.03.15
[Effective Java] toString을 항상 재정의하라  (0) 2020.03.14
[Effective Java] equals를 재정의하거든 hashCode도 재정의하라  (0) 2020.03.14
'언어/JAVA' 카테고리의 다른 글
  • [Effective Java] public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라
  • [Effective Java] 클래스와 멤버의 접근 권한을 최소화하라
  • [Effective Java] clone 재정의는 주의해서 진행하라
  • [Effective Java] toString을 항상 재정의하라
지나가던 개발자
지나가던 개발자
지나가던 개발자
나의 발전을 위한 공간
지나가던 개발자
전체
오늘
어제
  • 분류 전체보기 (221)
    • 언어 (86)
      • C++ (43)
      • JAVA (43)
    • 게임 개발 (4)
      • 간단한 RPG 게임 만들기 (4)
      • 게임 개발 이슈 해결 (0)
    • 백준 문제풀이 (36)
      • PLATINUM (0)
      • GOLD (13)
      • SILVER (21)
      • BRONZE (2)
    • 프로그래머스 문제풀이 (32)
      • LEVEL 5 (0)
      • LEVEL 4 (0)
      • LEVEL 3 (7)
      • LEVEL 2 (19)
      • LEVEL 1 (6)
    • SQL 문제풀이 (15)
      • 프로그래머스 (4)
      • 해커랭크 (11)
    • 디자인 패턴 (1)
    • 웹 (17)
      • 웹 이론 정리 (17)
    • CS 지식 (28)
      • 알고리즘 (0)
      • 데이터베이스 (11)
      • 자료구조 (0)
      • 네트워크 (7)
      • 그래픽스 (0)
      • 운영체제 (9)
      • 기타 (1)
    • Git (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 깃 허브

공지사항

인기 글

태그

  • Chapter 6
  • 객체 생성과 파괴
  • 소멸자 및 대입 연산자
  • 클래스와 인터페이스
  • 해커랭크
  • BOJ
  • 백준
  • mysql
  • 상속
  • 열거 타입과 애너테이션
  • 객체 지향 설계
  • Level 2
  • 설계 및 선언
  • c++
  • Chapter 4
  • level 1
  • Silver 3
  • 프로그래머스
  • java
  • Gold 5

최근 댓글

최근 글

hELLO · Designed By 정상우.
지나가던 개발자
[Effective Java] Comparable을 구현할지 고려하라
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.