[Java] Comparator, Comparable 을 이용한 값의 비교와 정렬

김지환·2023년 1월 10일
2

Comparator, Comparable 차이

Comparator, Comparable 모두 객체간 값의 비교를 위해서 필요한 메서드를 정리해놓은 인터페이스이다.

Primitive 객체 ( Integer, Char etc... ) 는 이미 비교 메서드가 구현이 돼있기 때문에 따로 정의해줄 필요가 없다.

사용자 정의 객체를 사용하거나 class 내에서의 특수한 상황속에 비교 메서드를 구현할 필요가 있을 때 사용하게 된다. 혹은 기존 비교 방식이 아닌 다른 방식의 비교를 사용하고 싶을 때 사용할 수 있다.

Comparator 인터페이스를 기반으로 비교 메소드를 정의하기 위해서는 반드시 compare 함수를 Override 해줘야한다. 이 때 compare 함수는 2개의 인자를 받게되고 이를 대소비교 하여 크기를 비교한다.

public interface Comparator<T> {
    int compare(T o1, T o2);

두 개의 인자를 받아 서로를 비교하는 방식으로 선행인자가 o1, 후행인자가 o2 이다.

양수값을 반환하면 순서의 변화가 없고 음수 값이 반환되면 순서가 바뀌게 된다.

Comparable 인터페이스를 사용하기 위해서는 compareTo 메소드를 Override 해줘야한다.

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

Comparable 은 자기자신과 입력받은 인자를 서로 비교하여 크기비교를 한다.

Comparable 돌 Comparator 와 같이 양수일 때 순서가 그대로 음수일 때 서로 바뀌는 방식으로 동작된다.

둘의 차이는 Comparable 인터페이스는 자기 자신과 입력값의 비교라면 Comparator는 자기자신과 무관하게 입력받은 두 인자값을 비교한다는 점이다.

Student라는 사용자정의 객체를 만들어서 Comparable을 이용한 비교 방식 그리고 Comparator를 이용하는 비교 방식을 구현해보면 아래와 같다.

public class Foo {
    @Test
    public void main() {
        Student studentA = new Student("Jisu", 26);
        Student studentB = new Student("Jennie", 23);
        Student studentC = new Student("Chan", 20);
        List<Student> students = new ArrayList<>();
        students.add(studentA);
        students.add(studentB);
        students.add(studentC);
        
        Collections.sort(students);

        students.forEach(System.out::println);
        System.out.println();

        Collections.sort(students, new StudentComparator());
        // students.sort(new StudentComparator());

        students.forEach(System.out::println);

    }
    static class StudentComparator implements Comparator<Student> {

        @Override
        public int compare(Student o1, Student o2) {
            if (o1.age < o2.age) {
                return 1;
            } else if (o1.age > o2.age) {
                return -1;
            } else {
                return 0;
            }
        }
    }
    static class Student implements Comparable<Student> {
        private String name;
        private int age;

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

        @Override
        public int compareTo(Student o) {
            if (this.age > o.age) {
                return 1;
            } else if (this.age < o.age) {
                return -1;
            } else {
                return 0;
            }
        }

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
}
Student{name='Chan', age=20}
Student{name='Jennie', age=23}
Student{name='Jisu', age=26}

Student{name='Jisu', age=26}
Student{name='Jennie', age=23}
Student{name='Chan', age=20}

작성한 두 개의 인터페이스 모두 Collections.sort 를 통해서 정렬을 진행할 수 있다.
Comparator 같은 경우에는 Collections 기반의 객체들 자체적으로 sort method 가 있기 때문에 이를 이용해서 정렬을 할 수도 있다. ( 주석 처리한 부분 참고 )

정렬에는 Arrays.sort 를 이용할 수도 있으나 Collection 기반 객체는 사용할 수 없고 배열 형태의 객체에만 사용할 수 있다.

profile
Developer

0개의 댓글