Java
[Java] Comparator, CompareTo, thenComparing
bornsoon
2025. 4. 28. 12:48
CompareTo란 정렬할 때 객체끼리 비교하는 방법을 정의하는 함수이다.
배열을 Arrays.sort()할 때,
int[]나 String[]처럼 기본 타입 외의
사용자가 정의한 클래스는 어떤 기준으로 비교할지 알려줘야 하기 때문이다.
compareTo | Comparator |
클래스 안에 "implements Comparable" 하고 compareTo 작성 |
"Arrays.sort(배열, (a, b) -> {})" 로 정렬 기준 따로 작성 |
클래스 수정 필요 | 클래스 수정 없이 외부에서 기준 설정 |
코드가 클래스에 묶여있음 | 정렬할 때마다 다른 기준을 쉽게 줄 수 있음 |
compareTo 사용법
a.compareTo(b) | 반환값 | |
a < b | -1 | a가 b보다 앞 |
a == b | 0 | |
a > b | 1 | a가 b보다 뒤 |
Comparator사용법
Arrays.sort(배열, (a, b) -> 비교하는 코드); |
< compareTo 예시 >
static class Meeting implements Comparable<Meeting> {
int start;
int end;
Meeting(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public int compareTo(Meeting other) {
if (this.end == other.end) {
return this.start - other.start; // 끝나는 시간이 같으면 시작 시간이 빠른 순
}
return this.end - other.end; // 끝나는 시간이 빠른 순
}
※ 사용자 정의 클래스는 Comparable 인터페이스를 구현하는 클래스여야함!!
→ implements Comparable<T> & @Override, CompareTo 필요
예제: [백준 1931번: 회의실 배정]
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
public class Main {
static class Meeting implements Comparable<Meeting> {
int start;
int end;
Meeting(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public int compareTo(Meeting other) {
if (this.end == other.end) {
return this.start - other.start; // 끝나는 시간이 같으면 시작시간 빠른 순
}
return this.end - other.end; // 끝나는 시간 기준 정렬
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
Meeting[] meetings = new Meeting[n];
for (int i = 0; i < n; i++) {
String[] time = br.readLine().split(" ");
int start = Integer.parseInt(time[0]);
int end = Integer.parseInt(time[1]);
meetings[i] = new Meeting(start, end);
}
Arrays.sort(meetings);
int count = 0;
int meetingEnd = 0;
for (Meeting meeting : meetings) {
if (meeting.start >= meetingEnd) {
count++;
meetingEnd = meeting.end;
}
}
System.out.println(count);
}
}
이 코드를 람다(lambda)식으로 적용해서 Comarator로 바꾸면
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
public class Main {
static class Meeting {
int start;
int end;
Meeting(int start, int end) {
this.start = start;
this.end = end;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
Meeting[] meetings = new Meeting[n];
for (int i = 0; i < n; i++) {
String[] time = br.readLine().split(" ");
int start = Integer.parseInt(time[0]);
int end = Integer.parseInt(time[1]);
meetings[i] = new Meeting(start, end);
}
Arrays.sort(meetings, (a, b) -> {
if (a.end == b.end) {
return a.start - b.start; // 끝나는 시간이 같으면 시작 시간이 빠른 순
}
return a.end - b.end; // 끝나는 시간 빠른 순
});
int count = 0;
int meetingEnd = 0;
for (Meeting meeting : meetings) {
if (meeting.start >= meetingEnd) {
count++;
meetingEnd = meeting.end;
}
}
System.out.println(count);
}
}
Comparator 이어붙이기 (thenComparing)
정렬 기준을 여러 개 순서대로 적용
<예시>
끝나는 시간이 빠른 순 → 같으면
시작 시간이 빠른 순
Arrays.sort(meetings,
Comparator.comparingInt((Meeting m) -> m.end) // 끝나는 시간 기준
.thenComparingInt(m -> m.start) // 끝나는 시간 같으면 시작 시간 기준
내림차순으로 하고 싶으면, reversed() 추가!
Arrays.sort(meetings,
Comparator.comparingInt((Meeting m) -> m.end)
.reversed() // end 기준 내림차순
.thenComparingInt(m -> m.start) // 그 다음 start 기준 오름차순
);
더 많이 조립해서 써본 예시
Arrays.sort(meetings,
Comparator.comparingInt((Meeting m) -> m.end) // 1. 끝나는 시간 기준
.thenComparingInt(m -> m.start) // 2. 시작 시간 기준
.thenComparingInt(m -> (m.end - m.start)) // 3. 길이 짧은 순
Comparator 객체 따로 만들기
Comparator<Meeting> meetingComparator =
Comparator.comparingInt((Meeting m) -> m.end)
.thenComparingInt(m -> m.start)
.thenComparingInt(m -> (m.end - m.start));
Arrays.sort(meetings, meetingComparator);
728x90