Comparable & Comparator

헨도·2025년 8월 21일

Java

목록 보기
8/8
post-thumbnail

Comparable

Comparable 인터페이스는 객체 스스로가 자연적인 정렬 순서를 정의하도록 한다.

정의

클래스 내부에 compareTo(Object o) 메소드를 구현하여 객체의 기본 정렬 기준을 정의

public interface Comparable<T> {...}

패키지

java.lang.Comparable<T>

메서드

int compareTo(T o)

  • 음수 : 현재 객체(this)가 o보다 작음
  • 0 : 같음
  • 양수 : 현재 객체(this)가 o보다 큼

객체 자체에 정렬 로직이 내장되므로, 해당 객체의 리스트나 배열을 Collections.sort() 또는 Arrays.sort() 메서드로 바로 정렬할 수 있다.

사용 예제

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

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

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

    // compareTo 구현 → 나이를 기준으로 오름차순 정렬
    @Override
    public int compareTo(Student other) {
        return this.age - other.age;
    }

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

public class Main {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student("철수", 22));
        list.add(new Student("영희", 20));
        list.add(new Student("민수", 25));

        // Comparable 기준(나이순)으로 정렬됨
        Collections.sort(list);

        System.out.println(list);
        // 출력: [영희(20), 철수(22), 민수(25)]
    }
}

단점

하나의 클래스에 오직 하나의 정렬 기준만 정의할 수 있다.
예를 들어, Book 클래스가 가격 기준으로 Comparable을 구현하면, 제목이나 저자 순으로 정렬하려면 다른 방법을 찾아야 한다.

Comparator

Comparator 인터페이스는 클래스 외부에서 사용자 정의 정렬 기준을 정의할 때 사용

정의

별도의 클래스나 람다 표현식으로 compare(Object o1, Object o2) 메서드를 구현하여 두 객체를 비교하는 로직 정의

public interface Comparator<T> {...}

패키지

java.util.comparator<T>

메서드

int compare(T o1, T o2)

  • 음수 : o1 < o2
  • 0 : o1 == o2
  • 양수 : o1 > o2

Collections.sort(List list, Comparator c)와 같이 정렬할 컬렉션과 함께 Comparator 객체를 전달하여 사용

사용 예제

import java.util.*;

class Student {
    private String name;
    private int age;
    private int score;

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

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

    @Override
    public String toString() {
        return name + "(" + age + "세, 점수:" + score + ")";
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student("철수", 22, 80));
        list.add(new Student("영희", 20, 95));
        list.add(new Student("민수", 25, 70));

        // 1. 나이순 (오름차순)
        Collections.sort(list, new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                return s1.getAge() - s2.getAge();
            }
        });
        System.out.println("나이순: " + list);

        // 2. 점수순 (내림차순)
        Collections.sort(list, (s1, s2) -> s2.getScore() - s1.getScore());
        System.out.println("점수순: " + list);

        // 3. 이름순 (알파벳순)
        list.sort(Comparator.comparing(Student::getName));
        System.out.println("이름순: " + list);
    }
}

장점

객체 자체를 수정하지 않고도 다양한 정렬 기준을 추가할 수 있다.
즉, 같은 Book 객체 리스트라도 가격, 제목, 저자 등 여러 기준으로 정렬이 가능하다.
또한, 클래스 자체에 접근할 수 없거나 여러 개의 정렬 기준이 필요할 때 유용하다.

비교

ComparableComparator
위치java.lang 패키지java.util 패키지
메소드int compareTo(T o)int compare(T o1, T o2)
정렬 기준객체의 자연적 순서(기본 정렬)사용자 정의 순서(외부 정렬)
구현정렬 대상 클래스 내부별도의 클래스나 람다 표현식
유연성한가지 정렬만 가능여러가지 정렬 가능
profile
Junior Backend Developer

0개의 댓글