반응형
Notice
Recent Posts
Recent Comments
Link
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

지식조각모음

Comparator와 Comparable 본문

책/자바의 정석

Comparator와 Comparable

y00 2022. 3. 10. 21:58
반응형

11장을 읽다가 이 부분만 따로 정리하고 싶어서 새 글을 작성했다.

1. Comparator와 Comparable 소개

먼저 Comparator와 Comparable 모두 인터페이스이다. 둘 다 컬렉션 정렬에 필요한 메소드를 정의해 놓았다는 공통점이 있다.

Interface Comparator<T>
Interface Comparable<T>

그러면 왜 이런 인터페이스가 필요할까? 먼저 기본 자료형(primitive type)은 부등호로 비교가 가능하다.

int a = 1;
int b = 2;

if (a == b) {
    return true;
} else {
    return false;
}

하지만 그 외 클래스는 어떻게 비교할 수 있을까?

2. 왜 사용할까?

public class Test {
    public static void main(String[] args)  {

        Student a = new Student();
        Student b = new Student();

        // a와 b비교????
    }
}

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

    // getter, setter 생략
}

Student a와 Student b를 비교하려고 할 때

  1. 어떤 기준으로 비교할 것인가
  2. 기준이 되는 값을 어떤 방식으로 비교할 것인가
    를 고려하여 매번 비교 메서드를 작성해야 한다. 아래 예시처럼 기준을 매번 정해야하고 매번 새로 정의해줘야 한다.
public class Test {
    public static void main(String[] args)  {

        Student a = new Student();
        Student b = new Student();

        // a와 b비교 1
        // studentNumber를 기준
        if (a.studentNumber > b.studentNumber) {
            // a > b
        } else if (a.studentNumber < b.studentNumber) {
            // a < b
        } else {    // a.studentNumber == b.studentNumber
            // a == b
        }


        // a와 b비교 2
        // age 기준
        if (a.age > b.age) {
            // a > b
        } else if (a.age < b.age) {
            // a < b
        } else {    // a.age == b.age
            // a == b
        }
    }
}


public class Student {
    private int studentNumber;
    private int age;
    private String name;

    // getter, setter 생략

    // 또는
    public boolean compareTo(Student student) {
        // studentNumber를 기준
        if (this.studentNumber > student.studentNumber) {
            // this > student
        } else if (this.studentNumber < student.studentNumber) {
            // this < student
        } else {    // this.studentNumber == student.studentNumber
            // this == student
        }
    }
}

그러다보면 compareTo(), compare(), comparetWith() 처럼 같은 기능을 다양하게 각자 생각한 방식대로 구현할 것이고 그 기준과 구현방식이 중구난방일 것이다. 이런 문제점을 해결하기 위해 Comparable 또는 Comparator를 사용한다.(getter와 setter처럼 이해했다)

3. Comparator와 Comparable의 차이점

  • Comparable은 기본 정렬 기준을 구현하는데 사용하면 객체 자신(this)과 파라미터로 받은 객체를 비교한다.
public interface Comparable { 
    int compareTo(Object o); 
}
  • Comparator은 기본 정렬기준 외에 다른 기준으로 정렬하고자 할 때 사용한다.
public interface Comparator {
    int compare(Object o1, Object o2);
    boolean equals(Object obj);
}

4. Comparable

Comparable 인터페이스가 어떻게 정의되어 있는지 확인해보면,

public interface Comparable<T> {
    public int compareTo(T o);
}

주석을 제외하면 메소드 하나만 가지고 있고 제네릭 타입을 받는다. compareTo()는 비교하고자 하는 Object를 파라미터로 받는다. 반환 타입을 보면 int로 되어 있는데 자기 자신과 파라미터로 받은 object를 비교결과를 int로 반환한다.

  • 자기 자신이 더 작으면 -1 (negative integer)
  • 동일하면 0
  • 자기 자신이 더 크면 1 (positive integer)

이렇듯 Comparable을 사용해서 객체를 비교하려고 하면 기본적으로 Comparable 인터페이스를 상속받아야 한다. 이때 CompareTo() 을 반드시 구현해야 한다. 위의 Student 클래스를 Comparable를 사용해서 구현해보면 이렇다.


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

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

    @Override
    public int compareTo(Student student) {
        if (this.studentNumber > student.studentNumber) {
            return 1;
        } else if (this.studentNumber == student.studentNumber) {
            return 0;
        } else {
            return -1;
        }

        // 위 코드는 아래처럼 간단하게 바꿀수 있다.
        // return this.studentNumber - student.studentNumber;
    }
}

정리하면 Comparable를 사용하면 객체를 비교할 수 있다.

이 때, compareTo() 메소드를 반드시 구현해야 하며,
반환값은 자기 자신을 기준으로 비교 대상과의 차이 값을 intger로 반환한다.

Comparator

반응형

' > 자바의 정석' 카테고리의 다른 글

13. 스레드  (2) 2022.03.30
12. 제네릭스, 열거형, 애너테이션  (0) 2022.03.13
11. 컬렉션 프레임웍  (0) 2022.03.06
10. 날짜와 시간 & 형식화  (1) 2022.03.05
9. java.lang 패키지와 유용한 클래스  (0) 2022.03.03