Comparable vs Comparator

GoRuth·2025년 6월 14일

1. 자바에서의 정렬방식

Java에서 정렬 기준을 정의하는 방법은 두 가지.

  • Comparable 인터페이스 (Comparable<T>)
    • 자기 자신이 정렬 기준
    • 클래스 내부에 compareTo() 메서드를 구현해 정렬 기준을 정의.
  • Comparator 인터페이스 (Comparator<T>)
    • 외부에서 정렬 기준을 주입.
    • 주로 익명 클래스나 람다식으로 사용.

2. 동작 과정

자바의 정렬 메커니즘은 객체 간의 우선순위를 비교하여 결정하는 방식으로 작동.

3. Comparable & Comparator

Comparable

  • 객체가 Comparable 인터페이스를 구현하고 있다면, compareTo() 메서드가 객체 간 비교에 사용됨
  • ex) PriorityQueue, Collections.sort() 등은 내부에서 자동으로 compareTo()를 호출해 순서 결정
  • 내부적으로는 힙 구성, 정렬 알고리즘 수행 등에서 다수의 비교가 발생, 매번 compareTo()를 통해 정렬 기준을 판단

Comparator

  • 객체가 Comparable을 구현하지 않은 경우 또는 다른 정렬 기준이 필요할 때, 외부에서 Comparator를 주입함
  • 주로 PriorityQueue, Arrays.sort, Collections.sort 등에서 두 번째 인자로 전달함
  • Comparator는 함수형 인터페이스, compare(x, y) 메서드를 통해 정렬 우선순위를 정의함
  • 일반적으로 람다식으로 많이 사용, 특정 필드 기준 정렬, 역순 정렬, 복합 정렬 등 다양한 패턴에 유용함

4. 각 동작마다 차이점

항목ComparableComparator
비교 위치클래스 내부외부에서 정의
코드 유지보수클래스 수정 필요외부에서 유연하게 변경 가능
다중 정렬 기준불가능 (1개만 정의)가능 (여러 Comparator 조합 가능)
성능빠름 (직접 구현, 메서드 호출 적음)약간 느림 (람다/익명 클래스 오버헤드)
재사용성낮음높음

4. 실제 문제로 알아보기 (백준 11286 - 절댓값 힙)

두 방식으로 모두 구현 가능

1) Comparable 사용

static class Numbers implements Comparable<Numbers> {
    int value;

    Numbers(int value) {
      this.value = value;
    }

    public int compareTo(Numbers other) {
      if (Math.abs(value) == Math.abs(other.value)) {
        return Integer.compare(value, other.value);
      } else {
        return Integer.compare(Math.abs(value), Math.abs(other.value));
      }
    }
  }
  • 장점: 성능 빠름, 가독성 좋음
  • 단점: 한 클래스에 하나의 정렬 기준만 넣을 수 있음

2) Comparator 사용

PriorityQueue<Integer> pq =
        new PriorityQueue<>((x, y) -> {
          return Math.abs(x) == Math.abs(y)
              ? (x > y ? 1 : -1)
              : (Math.abs(x) > Math.abs(y) ? 1 : -1);
        });
  • 장점: 코드가 짧고 유연함, 정렬 기준을 외부에서 바꿀 수 있음
  • 단점: 성능적으로 비교가 많을 경우 약간 느릴 수 있음

속도 비교 (체감 기준)

Comparable

Comparator

  • Comparable 방식이 일반적으로 약간 더 빠름 (정렬 기준이 객체 내부에 고정되어 있기 때문!)
  • Comparator는 유연하지만, 매번 비교 시마다 람다 호출 오버헤드가 있음

5. 느낀점

처음에는 람다의 편의성과 큰 차이점을 못느껴서 항상 Comparator를 사용했었지만, Comparable를 사용한 정렬방식이 훨씬 속도가 빠르다는 점을 알게 되어 추후에는 Comparable를 구현한 정렬방식을 더 많이 사용할 것 같다.

profile
Backend Developer

0개의 댓글