Java Study

Comparator와 Comparable 완전 정복 가이드: 자바 객체 정렬의 핵심

초코너무조코 2025. 2. 8. 22:57
728x90

자바에서 객체를 정렬하는 것은 매우 흔한 작업입니다. 하지만 단순히 Arrays.sort()를 사용하거나 컬렉션을 정렬하려고 하면, 컴파일 오류가 발생하거나 예상치 못한 결과가 나올 수 있습니다. 이는 자바가 객체의 "크기"를 어떻게 비교해야 하는지 모르기 때문입니다.

이 문제를 해결하기 위해 자바는 Comparable과 Comparator라는 두 가지 인터페이스를 제공합니다. 이 두 인터페이스를 이용하면 객체의 크기를 비교하는 방법을 정의하고, 이를 바탕으로 다양한 방식으로 객체를 정렬할 수 있습니다.

1. Comparable: "기본적인" 비교 방법 제시

Comparable 인터페이스는 "자기 자신"과 다른 객체를 비교하는 방법을 정의합니다. 즉, 객체 자체가 다른 객체와 어떻게 비교될 수 있는지 "기본적인" 비교 방법을 제공합니다.

Comparable 인터페이스

public interface Comparable<T> {
    public int compareTo(T o);
}
  • compareTo(T o) 메서드는 자기 자신(this)과 다른 객체(o)를 비교하여 정수 값을 반환합니다.
    • this < o: 음수 반환
    • this == o: 0 반환
    • this > o: 양수 반환

Comparable 구현 예시: Student 클래스

public class Student implements Comparable<Student> {
    String name;
    int grade;

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

    @Override
    public int compareTo(Student o) {
        // 학년 순으로 비교 (내림차순)
        return Integer.compare(o.grade, this.grade);
    }
}
  • Student 클래스는 Comparable<Student> 인터페이스를 구현하여 compareTo() 메서드를 오버라이드합니다.
  • compareTo() 메서드는 학생의 학년을 비교하여 정수 값을 반환합니다. 학년이 높을수록 "크다"고 판단합니다.

Comparable 사용 예시

Student[] students = {
    new Student("Alice", 3),
    new Student("Bob", 2),
    new Student("Charlie", 4)
};

Arrays.sort(students); // Comparable에 정의된 비교 방법을 사용하여 정렬

for (Student student : students) {
    System.out.println(student.name + ": " + student.grade);
}
  • Arrays.sort() 메서드는 Student 객체 배열을 정렬합니다.
  • Student 클래스가 Comparable 인터페이스를 구현했기 때문에, Arrays.sort() 메서드는 compareTo() 메서드를 사용하여 학생 객체를 비교하고 정렬합니다.

2. Comparator: "다양한" 비교 방법 제시

Comparator 인터페이스는 두 개의 객체를 비교하는 방법을 정의합니다. 즉, 객체 자체의 비교 방법 외에 "다양한" 비교 방법을 제공합니다.

Comparator 인터페이스

public interface Comparator<T> {
    int compare(T o1, T o2);
    // ... other methods
}
  • compare(T o1, T o2) 메서드는 두 개의 객체(o1, o2)를 비교하여 정수 값을 반환합니다.
    • o1 < o2: 음수 반환
    • o1 == o2: 0 반환
    • o1 > o2: 양수 반환

Comparator 구현 예시: StudentNameComparator 클래스

public class StudentNameComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        // 이름 순으로 비교 (오름차순)
        return o1.name.compareTo(o2.name);
    }
}
  • StudentNameComparator 클래스는 Comparator<Student> 인터페이스를 구현하여 compare() 메서드를 오버라이드합니다.
  • compare() 메서드는 학생의 이름을 비교하여 정수 값을 반환합니다. 이름이 사전 순으로 빠를수록 "작다"고 판단합니다.

Comparator 사용 예시

Student[] students = {
    new Student("Alice", 3),
    new Student("Bob", 2),
    new Student("Charlie", 4)
};

Arrays.sort(students, new StudentNameComparator()); // Comparator를 사용하여 정렬

for (Student student : students) {
    System.out.println(student.name + ": " + student.grade);
}
  • Arrays.sort() 메서드는 Student 객체 배열을 정렬합니다.
  • StudentNameComparator 객체를 Arrays.sort() 메서드에 전달하여, 이름 순으로 학생 객체를 비교하고 정렬합니다.

3. Comparable vs Comparator

 

특징 Comparable Comparator
비교 대상 자기 자신 vs 다른 객체 두 개의 객체
비교 방법 "기본적인" 비교 방법 "다양한" 비교 방법
구현 위치 객체 클래스 별도의 클래스
사용 예시 Arrays.sort(arr) Arrays.sort(arr, comparator)

결론

  • Comparable은 객체 자체의 "기본적인" 비교 방법을 정의할 때 사용합니다.
  • Comparator는 객체를 "다양한" 기준으로 비교하거나, 객체 클래스를 수정하지 않고 비교 방법을 변경하고 싶을 때 사용합니다.

Comparable과 Comparator를 적절히 활용하면 자바에서 객체를 효율적으로 정렬하고 관리할 수 있습니다.

728x90