티스토리 뷰

반응형

Comparable 인터페이스를 이용한 기본정렬에 대한 것은 이전 포스팅을 참고 ☞ List 정렬하기 - 1. Comparable 인터페이스

Comparable vs Comparator

클래스 개발자가 Comparable 인터페이스를 구현해서 정해둔 기본 정렬 이외에 다른 방식으로, 정렬하고 싶은 경우에는 이름 비슷한 Comparator인터페이스를 이용해야 한다. 기본 정렬 이외에 방식이라는 것은 다른 필드값을 기준으로 정렬하고 싶은 경우나, 정렬방식을 변경하고 싶은 경우를 말한다. 

아래 예제를 살펴보자

class BookNameComparator implements Comparator<book> {
    @Override
    public int compare(Book o1, Book o2) {
        return o1.getName().compareTo(o2.getName());
    }
}

Book이라는 클래스는 본래 price(가격)의 오름차순이 기본정렬로 되어있었다. 하지만 Book클래스를 name(이름)의 오름차순으로 정렬하기 위해 BookNameComparator라는 이름으로 '별개의' 클래스를 선언했다. 그리고 이 클래스는 Comparator 인터페이스의 compare라는 메소드를 위와같이 오버라이딩 했다.

정렬을 담당하는 메소드(Collections.sort)가 정렬을 하는 원리는 compareTo 메소드와 유사하고, 내부적으로 compareTo 메소드를 이용한다. 반환값 int가 양수이면 현재 객체 (compare 메소드를 호출한 객체)가 매개변수로 받은 객체보다 뒷쪽으로 이동으로, 0이면 정렬이 유지되고, 음수이면 현재 객체가 앞쪽으로 이동하게 된다. 정렬을 담당하는 메소드는 이런식으로 하나씩 비교해서 각 객체들을 정렬한다. 이 원리를 이용하면 오름차순으로 진행할지 내림차순으로 진행할지 개발자가 결정 할 수 있다. 실습을 직접 진행해본다면 이해하기 어렵지 않을 것이다. 참고로 문자 간의 연산이 가능한 이유는 문자를 구현하는 유니코드도 숫자로써 구분되고 이 숫자들이 사전순으로 정렬되어 있기 때문에 가능하다.

public class SortTester {
    public static void main(String[] args) {
        ArrayList bookList = new ArrayList<>();
        bookList.add(new Book("자바의정석", 9000));
        bookList.add(new Book("홍길동전", 6000));
        bookList.add(new Book("김소월 시집", 8000));

        Collections.sort(bookList,new BookNameComparator());
    }
}

Collections.sort()메소드를 이용하여서 정렬을 진행하였는데, 두번째 매개변수로 위에 선언한 BookNameComparator를 주었다.

for (Book book : bookList) {
    System.out.println(book.getName()+":"+book.getPrice());
    //출력결과 (이름의 오름차순 정렬)
    //김소월 시집:8000
    //자바의정석:9000
    //홍길동전:6000
}

이제 이 List의 순서를 출력해보면 BookNameComparator에 의도인 이름의 오름차순 정렬이 됐음을 알 수 있다. 

내림차순으로 정렬하기 (정렬방식 변경하기)

@Override
public int compare(Book o1, Book o2) {
    //return o1.getName().compareTo(o2.getName());
    return o2.getName().compareTo(o1.getName());
}

compare메소드를 위와같이 변경해보자. 정렬 원리를 생각해서 양수로 리턴되던 값을 음수로 리턴되도록 객체(o1과 o2의) 위치를 바꾸었다.

Collections.sort(bookList, new BookNameComparator());
for (Book book : bookList) {
    System.out.println(book.getName()+":"+book.getPrice());
    //출력결과 (이름의 내림차순 정렬)
    //홍길동전:6000
    //자바의정석:9000
    //김소월 시집:8000
}

이제 다시 정렬을 진행한 후, List의 순서를 출력해보면 이름의 내림차순 정렬이 됐음을 알 수 있다.

반응형
댓글