이펙티브 자바 아이템14 - Comparable 구현할지 고민해라

d-h-k·2021년 4월 19일
0

Comparable 인터페이스의 메서드 compareTo

  • Comparable 인터페이스의 유일한 메서드임
  • compareTo는 Object의 메서드가 아니다
  • Object의 equals와 다른점이 두가지인데
    • compareTo는 순서까지 비교 가능하다(equals는 단순 동치성만 비교)
    • 제네릭하다
  • Comparable구현은 클래스 인스턴스들에게 자연적으로 순서가 있는거임
    • 그래서 정렬도 가능함


Comparable 인터페이스 구현해 얻는 장점

public class WordList {
	public static void main(String[] args) {
    	Set<String> s = new TreeSet<>();
        Collections.addAll(s,args);
        System.out.println(s);
    }
}
  • 스트링클래스가 Collections 인터페이스를 구현했기때문에 위같은 코드가 가능하다
  • 책의 표현으로는 "좁쌀만한 노력으로 코끼리같은 효과"
  • 자바플랫폼의 대부분의 라이블러리와 클래스 , 열거형이 이 콤패러블을 구현했다
  • 결국 순서가 명확한 것이라면 콤패러블을 붙여주자


Comparable 규약

  • 두 객체를 서로 비교했을때 대/소 관계가 항상 일정해야함
  • compareTo 결과는 equals 결과랑 항상 같아야 함

compareTo 결과와 equals 결과가 다른 Bigdecimal 클래스

  • 그런게 있긴한데 읽어도 뭔지 몰라유.. ㅎㅎ


compareTo 메서드

자바 1.6 이전 시절

  • compareTo 메서드에서 정수 기본 타입 필드를 비교할 때는 관계연산자인 <와>를 사용
  • 실수 기본 타입 필드를 비교할 때는 정적메서드 사용(Double.compare, Float.compare)

자바 1.7 이후

  • 박싱된 기본 타입 클래스들에 새로 추가된 정적 메서드인 compare를 사용해라

왜냐하면

  • 가장 핵심적인 필드부터 비교해나가자 >> 클래스에 핵심 필드가 여러 개라면 어느것을 먼저 비교하느냐가 중요하기 때문
  • 비교 결과가 0이 아니라면 >> 순서가 결정된거고 >> 그러면 거기가 끝이다 곧장 반환하자
  • 가장 핵심이 되는 필드가 똑같다면, 같지않은 필드를 찾을때까지 그다음 중요한 순서로 필드를 비교해나간다

예제) 아이템10, PhoneNumber클래스용 compareTo 구현하기

  • 과거버전
public int compareTo(PhoneNumber pn) {
	int result = Short.compare(areaCode, pn.areaCode); 	//첫번째 중요한 필드
    if(result == 0) {						//두번째 중요한 필드
    	result = Short.compare(prefix,pn.prefix);
    
    	if(result == 0) {					//세번째 중요한 필드
        	result = Short.compare(lineNum,pn.lineNum);
        }
    }
    return result;
}

  • 자바 static import 기능을 활용해서 compareTo 에 적용한 방식
private static final Comparator<PhoneNumber> COMPARATOR = 
	comparingInt((PhoneNumber pn) -> pn.areaCode)
    	.thenComparingInt(pn -> pn.prefix)
        .thenComparingInt(pn -> pn.lineNum);

public int compareTo(PhoneNumber pn) {
	return Comparator.compare(this,pn);
profile
김동훈

관심 있을 만한 포스트

0개의 댓글