Back_End/Java

Java의 Comparator vs Comparable

10Biliion 2025. 2. 14. 12:17

 

 

 

Java에서 객체를 정렬할 때 사용하는 두 가지 인터페이스가 있습니다: Comparable과 Comparator입니다. 이 두 인터페이스는 컬렉션 내 객체를 정렬할 때 중요한 역할을 하며, 각각의 특징과 사용법이 다릅니다. 이번 글에서는 Comparable과 Comparator의 차이점을 설명하고, 예제와 함께 실무에서 어떻게 활용할 수 있는지 알아보겠습니다.


1. Comparable 인터페이스란?

Comparable 인터페이스는 클래스 자체에 정렬 기준을 정의할 때 사용합니다. 즉, 객체가 자신과 다른 객체를 비교할 수 있도록 합니다.

Comparable 인터페이스의 특징

  • java.lang.Comparable<T> 인터페이스를 구현해야 합니다.
  • compareTo(T o) 메서드를 오버라이딩하여 정렬 기준을 정의합니다.
  • Collections.sort(List<T>)를 사용할 때 기본 정렬 기준으로 작용합니다.
  • 한 가지 정렬 기준만 가질 수 있습니다.

Comparable 예제

import java.util.*;

class Person implements Comparable<Person> {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }

    @Override
    public int compareTo(Person other) {
        return Integer.compare(this.age, other.age); // 나이순 정렬
    }

    @Override
    public String toString() {
        return name + "(" + age + ")";
    }
}

public class ComparableExample {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 30));
        people.add(new Person("Bob", 25));
        people.add(new Person("Charlie", 35));
        
        Collections.sort(people); // 나이순 정렬
        System.out.println(people);
    }
}

출력 결과

[Bob(25), Alice(30), Charlie(35)]

위 코드에서는 Comparable을 구현하여 compareTo 메서드를 통해 age(나이)를 기준으로 오름차순 정렬을 수행했습니다.


2. Comparator 인터페이스란?

Comparator 인터페이스는 특정 기준에 따라 다양한 방식으로 정렬할 수 있도록 도와줍니다. Comparable과 달리 클래스 외부에서 정렬 기준을 정의할 수 있습니다.

Comparator 인터페이스의 특징

  • java.util.Comparator<T> 인터페이스를 구현해야 합니다.
  • compare(T o1, T o2) 메서드를 오버라이딩하여 정렬 기준을 정의합니다.
  • Collections.sort(List<T>, Comparator<T>)를 사용할 때 정렬 기준을 동적으로 설정할 수 있습니다.
  • 여러 개의 정렬 기준을 정의할 수 있습니다.

Comparator 예제

import java.util.*;

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }

    @Override
    public String toString() {
        return name + "(" + age + ")";
    }
}

public class ComparatorExample {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 30));
        people.add(new Person("Bob", 25));
        people.add(new Person("Charlie", 35));

        // 나이순 정렬
        people.sort(Comparator.comparingInt(Person::getAge));
        System.out.println("나이순 정렬: " + people);

        // 이름순 정렬
        people.sort(Comparator.comparing(Person::getName));
        System.out.println("이름순 정렬: " + people);
    }
}

출력 결과

나이순 정렬: [Bob(25), Alice(30), Charlie(35)]
이름순 정렬: [Alice(30), Bob(25), Charlie(35)]

위 코드에서는 Comparator.comparing을 활용하여 Person 객체를 나이순 정렬, 이름순 정렬 등 다양한 방식으로 정렬할 수 있었습니다.


3. Comparable vs Comparator 차이점

 

비교 항목 Comparable Comparator
패키지 java.lang java.util
사용 목적 기본 정렬 기준 제공 여러 개의 정렬 기준 제공
메서드 compareTo(T o) compare(T o1, T o2)
클래스 내/외부 클래스 내부에서 구현 클래스 외부에서 구현 가능
정렬 기준 한 가지 기준만 가능 여러 개의 기준 정의 가능
사용 예시 Collections.sort(list) Collections.sort(list, comparator) 또는 list.sort(comparator)

4. 정리

  • Comparable은 클래스 자체에서 정렬 기준을 정의하며, 한 가지 정렬 방식만 가질 수 있습니다.
  • Comparator는 클래스 외부에서 다양한 정렬 기준을 설정할 수 있으며, 여러 방식으로 정렬이 가능합니다.
  • Comparator.comparing을 활용하면 간결하게 정렬 기준을 정의할 수 있습니다.
  • 두 인터페이스를 적절히 활용하면 보다 유연하고 확장성 있는 정렬 로직을 구현할 수 있습니다.

 

 

  • Comparable은 기본적으로 정렬이 필요한 클래스에서 사용합니다. (예: Product, Employee 클래스 등)
  • Comparator는 다양한 정렬 기준이 필요한 경우 활용합니다. (예: 사용자 지정 정렬 옵션, 다중 정렬 기준 등)
  • 자바 8 이상에서는 Comparator.comparing과 메서드 참조(::)를 적극 활용하여 가독성을 높이는 것이 좋습니다.