[JAVA] Comparator와 Comparable

    Comparator와 Comparable

    모두 인터페이스로 컬렉션을 정렬하는데 필요한 메서드를 정의하고 있으며, Comparable을 구현하고 있는 클래스들은 같은 타입의 인스턴스끼리 비교할 수 있는 클래스들이며, 기본적으로 오름차순으로 정렬되도록 구현되어 있다.

     

    알고리즘 문제를 풀 때 정렬 기준을 바꿔야 하는 경우가 많아 유용하게 쓰인다.

     

    👉 Comparable: 기본 정렬기준을 구현하는 데 사용 (클래스의 기본 정렬 기준을 재정의하는 데 사용)

    👉 Comparator: 기본 정렬 기준 외에 다른 기준으로 정렬하고자 할 때 사용 (클래스 단위가 아닌 객체마다 정렬 기준을 다르게 하는 데 사용)

     

    실제 소스:

     

    public interface Comparator{
    	int compare(Object o1, Object o2);
        boolean equals(Object obj);
    }
    
    public interface Comparable{
    	public int compareTo(Object o);
    }

    Comparable 사용 예시

    아래는 백준 1377 버블소트 소스 코드중 일부다. (전체코드)

    class Point implements Comparable<Point>{
        int value;
        int index;
    
        public Point(int value, int index) {
            this.value = value;
            this.index = index;
        }
    
        @Override
        public int compareTo(Point o) {  // value 기준 오름차순 정렬
            return this.value - o.value;
        }
    }

     

    compareTo의 정렬 기준

    리턴 결과가 양수일 때 (this.value > o.value)

    👉 매개변수로 들어온 o 객체가 더 작다고 판별되어 주체 객체와 대상 객체가 교체되어 정렬된다. (기본 정렬은 오름차순)

     

    리턴 결과가 음수일 때 (this.value < o.value)

    👉 매개변수로 들어온 o 객체가 더 크다고 판별되어 정렬을 유지한다.

     

    리턴 결과가 0일 때 (this.value = o.value)

    👉 매개변수로 들어온 o 객체와 값이 같다고 판별되어 정렬을 유지한다.

     

    내림차순으로 정렬하려면 아래와 같이 return 문에서 순서만 바꾸면 된다.

     

    @Override
    public int compareTo(Point o) { // value 기준 내림차순 정렬
        return o.value - this.value;
    }

     

    👉 Collections.sort(객체) 사용 시 대상 객체가 Comparable 인터페이스로 정의한 기준에 따라 정렬된다. 객체의 경우 정렬 기준을 정의하지 않고 Collections.sort(객체)를 사용하면 컴파일 에러가 난다.

    Comparator 사용 예시

    정렬 대상 클래스와 다른 기준으로 정렬할 경우 사용할 수 있다.

    Comparator<Point> comparator = new Comparator<Point>(){
        @Override
        public int compareTo(Point o) { // index 기준 내림차순 정렬
            return o.index - this.index;
        }
    }
    
    Arrays.sort(points, comparator);

     

    아래와 같이 합쳐서 작성할 수도 있다.

     

    Arrays.sort(points, new Comparator<Point>(){
        @Override
        public int compareTo(Point o) { // index 기준 내림차순 정렬
            return o.index - this.index;
        }
    });

     

    int 배열도 Comparable을 구현한 클래스이기 때문에 아래와 같이 작성할 수 있다.

    • 이차원 배열인 arr를 정렬
    • 배열의 두 번째 값이 같은 경우에는 첫 번째 값으로 오름차순 정렬을 하고, 그렇지 않을 경우는 두 번째 값으로 오름차순 정렬을 한다. 
    Arrays.sort(arr, new Comparator<int[]>() {
        @Override
        public int compare(int[] o1, int[] o2) {
            if (o1[1] == o2[1]) return o1[0] - o2[0];
            return o1[1] - o2[1];
        }
    });

     

    오름차순/내림차순, 첫 번째/두 번째 값 기준만 바꿔가면서 응용하면 알고리즘 문제를 풀 때 아주 유용하게 쓰이는 코드다.

     

     


    참고:

    자바의 정석 - 남궁성 p628-630

    https://yuja-kong.tistory.com/entry/Java-%EA%B0%9D%EC%B2%B4-%EC%A0%95%EB%A0%AC-Comparable-Comparator

     

     

    728x90

    댓글