java로 코딩 테스트 공부를 하면서 필요하다고 느낀 Comparable 과 Comparator 에 대해 알아보자.
둘 다 객체 정렬 기준을 만들기 위해 사용할 수 있다.
결론부터 말하면 함수형 인터페이스여서 람다로 Collections.sort() 의 두번째 인자로 전달할 수 있는 Comparator가 코딩테스트에서 더 유용한 것 같다.
Comparable
- 함수형 인터페이스가 아니다.
- 클래스 정의 시 implement 하고 comapreTo 메서드를 구현한다.
public int compareTo(T o);
- compareTo 는 자기 자신과 파라미터로 들어온 객체를 비교한다.
class Node implements Comparable<Node> {
int index;
int value;
public Node(int index, int value) {
this.index = index;
this.value = value;
}
// 오름차순 정렬
@Override
public int compareTo(Node other) {
return this.value - other.value;
}
- 내림차순은 반대로 other.value - this.value
Comparator
- 함수형 인터페이스
- 익명 클래스로 사용하거나, 람다로 사용 -> 함수형 인터페이스여서 가능
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
- 함수형 인터페이스여서 @FunctionalInterface 가 붙은 걸 확인할 수 있다.
- compare 는 파라미터로 들어온 o1, o2 를 비교한다.
// 익명 클래스
Collections.sort(nodes, new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
return o1.value - o2.value;
}
});
// 람다 -> 훨씬 편리함 !
Collections.sort(nodes, (o1, o2) -> o1.value - o2.value);
- 오름차순 : o1-o2 형태
- 내림차순 : o2-o1 형태
- 코딩테스트에서는 Comparator 를 람다 형태로 전달하는 방식이 간편하고, 유용했다.
Collections.sort 뿐만 아니라, PriorityQueue 생성자의 인자에도 람다 형태로 전달할 수 있다.
// jobs 큐
PriorityQueue<Work> jobQ = new PriorityQueue<>((w1,w2)->w1.reqTime-w2.reqTime);
// 작업 대기 큐
PriorityQueue<Work> waitQ = new PriorityQueue<>((w1,w2)->{
if (w1.needTime == w2.needTime){ // 소요시간이 같으면
if (w1.reqTime == w2.reqTime){ // 요청시각이 같으면
// 작업 번호 낮은 것부터
return w1.number-w2.number;
}
return w1.reqTime - w2.reqTime; // 요청시각이 빠른 것부터
}
return w1.needTime - w2.needTime; // 소요시간이 빠른 것부터
});
기준이 여러개일 때 예시 (작업 대기 큐) (출처 : 내 풀이)
코딩테스트에서 Override 하기에는 형태를 외우기 귀찮으니까 ? 나는 람다 사용이 더 맘에 든다 ^_^
'Java' 카테고리의 다른 글
Thread (2) | 2025.06.22 |
---|---|
조기축구 스쿼드메이커 만들기 (0) | 2025.01.27 |
Java 정렬 (0) | 2023.12.25 |
Java에서의 예외처리 (0) | 2023.12.15 |
StringBuilder, StringJoiner, String.format (1) | 2023.10.29 |