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