본문 바로가기
Language/JAVA

Comparable과 Comparator비교

by KeepCoding 2025. 3. 12.

ComparableComparator 은 둘 다 인터페이스(interface)이므로, 내부에 선언된 메소드를 구현해야 사용할 수 있다.

 

[Comparable]

Comparable를 살펴보면 내부에 compareTo(T o)만 Override 해주면 된다.

https://docs.oracle.com/javase/8/docs/api/

 

Java Platform SE 8

 

docs.oracle.com

 

[Comparator]

Comparator를 살펴보면 내부에 많은 메서드들이 있지만 compare(T o1, T o2)만 Override된다.

나머지 메서드들은 전부 기본구현(default 메서드)이 제공된다.

equals(Object obj)는 default 메서드는 아니지만 Object에서 상속받으므로 구현 하지 않아도 된다.

https://docs.oracle.com/javase/8/docs/api/

 

Java Platform SE 8

 

docs.oracle.com

Comparator vs Comparable!

1. 기본 개념

  Comparable  Comparator
정의 객체 자기 자신이 비교 기준을 가짐 외부에서 비교 기준을 따로 정의
패키지 java.lang (기본 제공) java.util (추가 필요)
메서드 int compareTo(T o) int compare(T o1, T o2)
비교 기준 위치 클래스 내부 (this와 o를 비교) 클래스 외부 (o1과 o2를 비교)
사용 목적 객체 자체가 "나 이런 기준으로 정렬돼!" 라고 주장할 때 외부에서 여러 개의 정렬 기준을 적용할 때
장점 기본 정렬 기준을 클래스에 직접 넣을 수 있음 여러 정렬 기준을 유연하게 설정 가능
단점 한 가지 기준만 가능 코드가 살짝 더 길어질 수 있음

2. 사용 방법

(1) Comparable - 같은 클래스 끼리 비교

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

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

    @Override
    public int compareTo(Person other) {
        return Integer.compare(this.age, other.age); // 나이 오름차순 정렬
    }
}
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));

Collections.sort(people); // 자동으로 compareTo 적용!

장점: 객체 자체가 비교 기준을 가지므로 sort() 호출만으로 정렬이 가능!
단점: 정렬 기준을 하나밖에 정의할 수 없음. (ex. 이름으로 정렬하려면 새로운 방법 필요)

(2) Comparator - 다른 클래스와도 비교 가능 (외부에서 정렬 기준 제공)

사용방법:

  • 인터페이스 구현 방식
import java.util.*;

class Person {
    String name;
    int age;

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

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

// 나이 기준 오름차순 정렬
class AgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return Integer.compare(p1.age, p2.age);
    }
}

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

        Collections.sort(people, new AgeComparator());
        System.out.println(people);  // [Bob (25), Alice (30), Charlie (35)]
    }
}​
  • 익명 클래스 사용

클래스를 따로 만들 필요 없이 익명 클래스로 바로 사용할 수도 있습니다.

Collections.sort(people, new Comparator<Person>() {
    @Override
    public int compare(Person p1, Person p2) {
        return Integer.compare(p1.age, p2.age);
    }
});
  • 람다식 사용
people.sort((p1, p2) -> Integer.compare(p1.age, p2.age));

//comparing사용
people.sort(Comparator.comparing(p -> p.age));

//::사용 (제일 깔끔하고 이해하기도 좋아보인다)
people.sort(Comparator.comparing(Person::age));

(2-1) 기능

//reversed(): 오름차순을 내림차순으로 변경 가능.
people.sort(Comparator.comparing(Person::getAge).reversed());

//comparing,thenComparing 나이가 같다면 이름순으로 정렬 가능.
people.sort(Comparator.comparing(Person::getAge).thenComparing(Person::getName));

3. 정리

  • 객체 자체가 정렬 기준을 가지는 게 적절하면 Comparable 사용.
  • 비교 기능을 외부로 빼기, 다중 정렬은 Comparator를 사용.
반응형

'Language > JAVA' 카테고리의 다른 글

@Retension (SOURCE,CLASS,RUNTIME)  (0) 2025.03.14