[JAVA] Comparable과 Comparator에 대하여

2025. 7. 20. 18:18·자바

컬렉션을 다룰 때 객체를 정렬하는 일은 자주 발생한다.


예를 들어 List<User>가 있다고 가정해보자. 이 리스트를 이름순으로 정렬하거나, 나이순으로 정렬하거나, 가입일 순으로 정렬할 수도 있다. 하지만 여기서 한 가지 문제가 있다.

 

자바는 int, String, double 같은 기본 타입은 어떤 값이 큰지, 작은지를 알고 있어서 정렬이 가능하다. 하지만 사용자가 정의한 클래스, 예를 들어 User 같은 객체는 어떤 속성을 기준으로 비교해야 하는지 알지 못하기 때문에 기본적으로 정렬이 불가능하다.

이 문제를 해결하기 위해 자바는 두 개의 비교 인터페이스를 제공한다.

  • Comparable<T>
  • Comparator<T>

두 인터페이스 모두 객체 간의 대소 비교를 가능하게 하지만, 사용 방식과 의도는 분명히 다르다. 지금부터 각각의 특징과 차이점, 예시, 실무 팁까지 정리해본다.

 

1. Comparable<T>: 객체 스스로 정렬 기준을 가진다

Comparable은 클래스 내부에서 자기 자신이 어떤 기준으로 정렬되어야 하는지를 정의하는 방식이다. 즉, 객체 자신이 "나는 이렇게 정렬되겠다"고 말하는 것과 같다.

public class User implements Comparable<User> {
    String name;
    int age;

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

    @Override
    public int compareTo(User other) {
        return this.age - other.age; // 나이 오름차순 정렬 기준
    }
}

위처럼 compareTo() 메서드를 오버라이드하면 Collections.sort()를 사용할 수 있다.

List<User> users = new ArrayList<>();
users.add(new User("Kim", 30));
users.add(new User("Lee", 25));
users.add(new User("Park", 20));

Collections.sort(users); // 나이순으로 정렬됨

이처럼 Comparable은 기본 정렬 기준을 객체 내부에 직접 정의하는 방식이다. 하지만 하나의 클래스에 하나의 기준밖에 정의할 수 없다는 한계가 있다.

 

2. Comparator<T>: 외부에서 정렬 기준을 지정한다

Comparator는 객체 외부에서 정렬 기준을 따로 정의하는 방식이다.
즉, 객체 내부를 수정하지 않고도 다양한 기준으로 정렬할 수 있다.

 

예시: 이름순 정렬

//오름차순
class NameComparator implements Comparator<User> {
    @Override
    public int compare(User u1, User u2) {
        return u1.name.compareTo(u2.name);
    }
}

//내림차순
class AgeDescendingComparator implements Comparator<User> {
    @Override
    public int compare(User u1, User u2) {
        return u2.age - u1.age; // 나이 내림차순
    }
}

사용:

Collections.sort(users, new NameComparator());
Collections.sort(users, new AgeDescendingComparator());

 

3. Comparable vs Comparator 정리

구분                            Comparable                                                        Comparator
정의 위치 클래스 내부에서 정의 클래스 외부에서 정의
메서드 이름 compareTo() compare()
정렬 기준 개수 하나만 가능 여러 개 기준 정의 가능
사용 방법 Collections.sort(list) Collections.sort(list, comparator)
예시 상황 기본 정렬이 명확할 때 (ex. 학생 번호) 다양한 기준이 필요할 때 (ex. 이름, 점수)

 

4. 실무 팁

  • 정렬 기준이 하나만 존재하면 Comparable을 사용하고,
  • 정렬 기준이 여러 개 존재하거나 객체를 수정할 수 없는 경우 Comparator를 사용한다.

 

마무리하며

객체를 정렬해야 할 때 자바는 Comparable과 Comparator라는 두 가지 도구를 제공한다.
정렬 기준이 고정이라면 Comparable, 기준이 다양하거나 외부에서 제어하고 싶다면 Comparator를 선택하자.

 

실무에서는 Comparator를 따로 만들어 두면 코드의 유연성과 가독성이 높아진다.
또한 Collections 유틸리티를 적극 활용하면 다양한 정렬, 비교, 섞기 작업을 쉽게 처리할 수 있다.

 

객체 정렬, 어렵지 않다. 핵심은 기준을 명확히 정의하고 그 기준을 어디에 둘지를 선택하는 것이다.

 

감사합니다.

 

'자바' 카테고리의 다른 글

[JAVA] 자바의 Iterable과 Iterator  (0) 2025.07.20
[JAVA] Map 인터페이스에 대하여 (4)  (0) 2025.07.20
[JAVA] Set 인터페이스에 대하여 (3)  (1) 2025.07.20
[JAVA] List에 인터페이스에 대하여 (2)  (5) 2025.07.18
[JAVA] 배열의 단점과 ArrayList, LinkedList 비교 (1)  (4) 2025.07.17
'자바' 카테고리의 다른 글
  • [JAVA] 자바의 Iterable과 Iterator
  • [JAVA] Map 인터페이스에 대하여 (4)
  • [JAVA] Set 인터페이스에 대하여 (3)
  • [JAVA] List에 인터페이스에 대하여 (2)
0kingki_
0kingki_
자바 + 스프링 웹 개발
  • 0kingki_
    0kingki_
    0kingki_
  • 전체
    오늘
    어제
    • 분류 전체보기 (134)
      • 코딩 테스트 (54)
      • 자바 (21)
      • 스프링 (27)
      • 타임리프 (16)
      • 스프링 데이터 JPA (8)
      • 최적화 (2)
      • QueryDSL (4)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    thymeleaf
    QueryDSL
    재귀
    코딩테스트
    스프링 데이터 JPA
    예외처리
    spring
    fetch join
    BFS
    SpringDataJpa
    스프링
    자바
    dfs
    스프링 컨테이너
    컬렉션
    SOLID
    타임리프
    mvc
    코딩 테스트
    예외 처리
    다형성
    객체지향
    쿼리
    백준
    최적화
    쿼리dsl
    LocalDateTime
    Java
    JPA
    불변객체
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
0kingki_
[JAVA] Comparable과 Comparator에 대하여
상단으로

티스토리툴바