-
Comparable 인터페이스를 구현할 때 비교자(Comparator) 이용하기Dev. Diary/Memo 2023. 9. 27. 16:17
책 Effective Java에서
Comparable
인터페이스에 관한 내용을 다루는 부분을 읽다가, 유용할 것 같은 코드를 알게 되었다.
클래스에서Comparable
인터페이스를 구현하고,compareTo()
메서드를 만들어서 객체들끼리 비교하도록 만드는 것을 우선순위 큐를 이용하여 알고리즘 문제를 해결할 때 많이 사용했었다. 그런데 클래스가 비교해야 할 필드가 여러 개 있을 경우에, 각각의 필드를 하나하나 다 비교해가며compareTo()
메서드를 구현해야 했었다. 아래는 BOJ 문제 강의실 2(1379)에서 사용된 클래스이다. 기존의 코드에서 클래스의 멤버들이 너무 자유분방해보여서 약간 수정했다.class Lecture implements Comparable<Lecture> { private int id, startTime, endTime; private Lecture(int id, int startTime, int endTime) { this.id = id; this.startTime = startTime; this.endTime = endTime; } public static Lecture create(int id, int startTime, int endTime) { return new Lecture(id, startTime, endTime); } @Override // 강의 시작 시간이 빠른 것부터 나열하도록 우선순위 설정 public int compareTo(Lecture otherLecture) { if (this.startTime == otherLecture.startTime) { if (this.endTime == otherLecture.endTime) { return this.id - otherLecture.id; } else return this.endTime - otherLecture.endTime; } else return this.startTime - otherLecture.startTime; } }
compareTo()
메서드만 보면 각각의 필드를 하나하나 비교하고 있다. 이 코드를 쓸 때도 좀 더 깔끔하게 쓸 수는 없을지 잠깐 생각했던 것 같은데, 그렇게 깊이 고민하지는 않았다. 책에서는 아래와 같은 코드를 추천해줬다.import java.util.Comparator; import static java.util.Comparator.comparingInt; class Lecture implements Comparable<Lecture> { private final int id, startTime, endTime; private static final Comparator<Lecture> COMPARATOR = comparingInt((Lecture l) -> l.startTime) .thenComparingInt(l -> l.endTime) .thenComparingInt(l -> l.id); private Lecture(int id, int startTime, int endTime) { this.id = id; this.startTime = startTime; this.endTime = endTime; } public static Lecture create(int id, int startTime, int endTime) { return new Lecture(id, startTime, endTime); } @Override public int compareTo(Lecture otherLecture) { return COMPARATOR.compare(this, otherLecture); } }
위의 코드에서는 클래스의 필드가 그렇게 많지 않아서 크게 차이가 없어보이지만, 필드가 더 많이 있을 때는
Comparator
를 사용하는 것이 코드를 쓰기도 좋고 보기도 좋을 것 같다. 약간의 성능 저하가 있다고는 하는데, 조건문 여러 개를 붙이는 것보다는 나을 것 같다.'Dev. Diary > Memo' 카테고리의 다른 글
requireNonNull() 메서드 관련 메모 (0) 2023.09.22 오토 박싱, 언박싱 조심! (0) 2023.09.20 객체의 일관성에 관한 메모 (0) 2023.09.19 정적 팩토리 메서드를 알아보다가 느낀 점 (0) 2023.09.17 입력을 받았을 때, 직접 input stream에서 데이터를 읽어오기 (0) 2023.08.28