티스토리 뷰

JAVA : Comparator / Comparable

List를 정렬할 때 기본형 데이터 타입은 정렬의 기준이 있기 때문에 Collections.sort(list)하면 정렬이 된다. 하지만 List안에 있는 데이터 타입이 기본형 데이터 타입이 아닐 경우(클래스 등) 정렬의 기준이 없기 때문에 컴파일 오류가 난다. 따라서 객체의 정렬 기준을 정의해야 한다.

Comparable

객체를 정렬하는 기준을 정의하는 방법 중 하나로 Comparable 인터페이스가 있다. 객체 간의 일반적인 정렬이 필요할 때, 자바에서 기본적으로 제공하는 Comparable 인터페이스를 확장해서 정렬의 기준을 정의하는 compareTo() 메서드를 구현한다.

class Student implements Comparable<Student> {
    ....
    @Override
    public int compareTo(Student o) {
        return this.getScore() - o.getScore();
      //return this.name.compareTo(o.name); 
    }
}

Comparable의 compareTo를 통해 인자로 넘어온 같은 타입의 다른 객체와 대소 비교가 가능하다. 메소드를 통해 넘어온 객체보다 작을 경우 음수를 리턴하고, 크기가 같으면 0, 크면 양수를 리턴한다.

Comparator

정렬 대상의 클래스를 수정할 수 없을 때, 정렬 하고자하는 객체에 이미 정렬의 기준이 존재할 때(즉, 다른 정렬 기준을 사용하고 싶을 때) 사용한다. 즉, 객체 간의 특별한 정렬이 필요할 때 Comparator 인터페이스를 확장해서 특정 기준을 정의하는 compare() 메서드를 구현한다.

Comparator<Student> comparator = new Comparator<Student>() {
    @Override
    public int compare(Student a, Student b) {
        return a.getScore() - b.getScore();
    }
};
Collections.sort(students, comparator);

Comparator의 compare 메소드는 2개의 비교할 객체를 인자로 받는다. 첫번째 객체가 두번째 객체보다 작으면 음수, 같으면 0, 크면 양수를 리턴한다.

정리

공통점은 정렬의 기준을 정의한다는 것이고,

차이점은 정렬 기준이 일반적이냐 일반적이지 않냐와 compareTo(Object o) 메서드를 구현하느냐 compare(Object o1, Object o2) 메서드를 구현하느냐가 전부다.

Example : Programmers - 베스트앨범

class album implements Comparable<album> {
    int idx;
    int plays;
    String genre;
    album(int idx, int plays, String genre) {
        this.idx = idx;
        this.genre = genre;
        this.plays = plays;
    }
    @Override
    public int compareTo(album o) {
        if (this.plays < o.plays) {
            return 1;
        } else if (this.plays == o.plays) {
            if (this.idx > o.idx) {
                return 1;
            }
        }
        return -1;
    }
}
public static List sortByValue(final Map map) {
        List<String> list = new ArrayList(map.keySet());
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                Integer v1 = (Integer) map.get(o1);
                Integer v2 = (Integer) map.get(o2);
                return v2 - v1;
            }
        });
        /*
          List<String> list = new ArrayList(map.keySet());
        Collections.sort(list, (Comparator) (o1, o2) -> {
            Object v1 = map.get(o1);
            Object v2 = map.get(o2);
            return ((Comparable) v2).compareTo(v1);
        });
         */
        return list;
    }

sortByValue 메소드는 HashMap<String,Integer>를 받아서 value를 기준으로 정렬하는 함수이다. 여기서 value가 integer라서 compare에서 형변환을 하여 정렬하였지만, 범용적?으로 사용할 때는 주석처리한 코드를 사용하면 좋을 것 같다.

 

즉, 두 인터페이스는 정렬규칙을 설정하기 위해 사용하며, 차이점을 한 줄로 정리하자면 다음과 같다. 

Comparable - 객체 스스로에게 부여하는 한 가지 기본 정렬 규칙을 설정하는 것이 목적이다.

Comparator - 기본 정렬 규칙과 다르게 원하는대로 정렬 기준을 지정하고 싶을 때(다른 정렬 기준을 사용하고 싶을 때) 사용한다.

 

'Java' 카테고리의 다른 글

JAVA Collection 시간 복잡도  (0) 2020.08.06
[Java] char to int  (0) 2020.03.23
[Java] JVM  (0) 2020.03.03
[Java] Singleton  (0) 2020.03.03
[Java] Interface  (0) 2020.03.03
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함