Java Comparator 이해하기

다람·2025년 1월 2일
0

Java

목록 보기
3/3
post-thumbnail

Comparator란?

Comparator는 객체를 비교해서 정렬 순서를 정해주는 Java 인터페이스다.
정렬 기준을 직접 정의할 수 있기 때문에 우리가 원하는 방식으로 데이터를 정렬할 때 유용하다.

1. Comparator 기본 사용법 (compare 메서드)

기본 구조

Comparator의 가장 핵심 메서드는 compare이다.
두 값을 비교해서 순서를 정렬해준다.

  • 음수 반환 : 첫 번째 값이 두 번째 값보다 앞에 배치된다. (오름차순)
  • 0 반환 : 두 값의 순서는 변경되지 않는다.
  • 양수를 반환 : 첫 번째 값이 두 번째 값보다 뒤에 배치된다. (내림차순)

숫자 정렬 예시

import java.util.*;

public class ComparatorExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(3, 5, 1, 4, 2);

        // 오름차순 정렬
        numbers.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2; // 작은 값이 앞으로
            }
        });

        System.out.println(numbers); // [1, 2, 3, 4, 5]

        // 내림차순 정렬
        numbers.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1; // 큰 값이 앞으로
            }
        });

        System.out.println(numbers); // [5, 4, 3, 2, 1]
    }
}

2. 람다와 Comparator (간단한 표현)

Java 8부터는 람다 표현식을 사용해서 Comparator를 간결하게 작성할 수 있다.

람다 작성 예시

numbers.sort((o1, o2) -> o1 - o2); // 오름차순
numbers.sort((o1, o2) -> o2 - o1); // 내림차순

람다를 사용하면 코드가 한 줄로 줄어들어서 깔끔해지는 것을 확인할 수 있다.

3. comparing과 comparingInt

comparing

Comparator.comparing은 특정 속성을 기준으로 정렬할 때 사용한다. 이를 사용하면 어떤 값을 기준으로 비교할지 지정할 수 있다.

문자열 길이로 정렬 예시

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Dave");

names.sort(Comparator.comparing(String::length));
System.out.println(names); // [Bob, Dave, Alice, Charlie]

동작 원리를 설명해보면
String::length는 문자열의 길이를 가져오는 메서드 참조방식이다. Comparator.comparing(String::length)를 사용하면 문자열의 길이를 기준으로 정렬할 수 있도록 기준을 잡아주는 것이다.

comparingInt

comparingInt는 정수 값을 기준으로 비교하는 Comparator를 생성한다. 그래서 정렬 기준이 정수형일 때 더 간단하게 사용할 수 있다.

2차원 배열 정렬 예시

int[][] points = {{3, 2}, {1, 4}, {5, 1}, {2, 3}};

// 첫 번째 값(x 좌표)을 기준으로 정렬
Arrays.sort(points, Comparator.comparingInt(o -> o[0]));

for (int[] point : points) {
    System.out.println(Arrays.toString(point));
}
// 출력:
// [1, 4]
// [2, 3]
// [3, 2]
// [5, 1]

참고. o -> o[0]는 뭘까?

람다 표현식 o -> o[0]은 다음과 같다.
o는 정렬하려는 배열(2차원 배열의 각 원소)이다.
o[0]은 배열의 첫 번째 값(예: x 좌표)을 의미한다.
즉, o[0]을 정렬 기준으로 사용하겠다는 의미인 것이다.

응용 예제

프로그래머스 Lv.0 Java-전국 대회 선발 고사

https://school.programmers.co.kr/learn/courses/30/lessons/181851

comparingInt를 사용해서 학생의 등수를 기준으로 정렬하도록 했다.

import java.util.*;
import java.util.stream.Collectors;

class Solution {
    public int solution(int[] rank, boolean[] attendance) {
        // rank와 attendance를 묶어서 처리
        List<Integer> top3 = new ArrayList<>();
        for (int i = 0; i < rank.length; i++) {
            if (attendance[i]) {
                top3.add(i); // 학생 번호 저장
            }
        }

        // rank 기준으로 정렬하여 상위 3명 추출
        top3 = top3.stream()
                .sorted(Comparator.comparingInt(i -> rank[i]))
                .limit(3)
                .collect(Collectors.toList());

        // 상위 3명 점수 계산
        return 10000 * top3.get(0) + 100 * top3.get(1) + top3.get(2);
    }
}

위의 풀이에서는 comparingInt를 사용했다.
i -> rank[i] 람다식을 사용하여 정렬 기준을 설정했다.

  • i : 학생 번호
  • rank[i] : 학생 번호 i에 해당하는 등수

Comparator.comparingInt(i -> rank[i])를 사용하여 rank 배열에서 등수를 기준으로 정렬하도록 한 것이다.

5. 정리

Comparator는 객체를 비교하는 인터페이스이다.

  • compare : 두 값을 비교한다.
  • comparing : 객체의 특정 속성을 기준으로 정렬 기준을 설정한다.
  • comparingInt : 정수 값에 대해 정렬 기준을 설정한다.
profile
개발하는 다람쥐

0개의 댓글