ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] 정렬 메소드 sort() / Comparable / Comparator
    Language/Java 2020. 7. 4. 16:56

     

     

    오늘은 자바에서의 자료구조의 정렬 메소드인 sort() 대해 정리하려고 합니다.

     

     

    1. Arrays.sort()

     

    java.util.Arrays 클래스에 포함되어있는 sort() 메소드를 이용해 배열을 정렬하는 것이 가능합니다.

     

     

    Primitive타입 배열

    public static void sort(primitive type array arr)

    primitive 타입의 배열을 인자로 받아 오름차순 정렬

    public static void sort(primitive type array arr, int fromIndex, int toIndex)

    primitive 타입의 배열, 시작 인덱스, 끝 인덱스를 인자로 받아 주어진 배열의 시작 인덱스부터 끝 인덱스까지의 데이터를 오름차순 정렬 

    primitive타입의 배열을 인자로 sort() 메소드를 호출하는 경우 오름차순으로 정렬됩니다.

    * 배열에 숫자, 영어, 한글이 함께 속해있다면 sort() 시, 숫자-알파벳-한글 순으로 정렬됩니다.

     

     

    Object타입 배열

     

    public static void sort(Object type array arr)

    Object 타입의 배열을 인자로 받아 natural ordering에 따라 정렬

    public static void sort(Object type array arr, int fromIndex, int toIndex)

    Object 타입의 배열을 인자로 받아 주어진 배열의 시작 인덱스부터 끝 인덱스까지의 데이터를 natural ordering에 따라 정렬

    Object타입의 배열의 경우 natural ordering에 따라 정렬합니다. natural ordering이란 무엇일까요? natural ordering은 직역하면 자연스러운 순서 라고 할 수 있습니다.

    말 그대로 자연스럽게 느껴지는 순서인 것입니다. 숫자 타입, 날짜 타입, 알파벳과 같은 문자 타입의 경우 자연스럽게 느껴지는 순서가 있는 타입들입니다.

     

    이러한 natural ordering을 가지는 클래스 타입은 Comparable 인터페이스를 구현한 클래스입니다. Comparable 인터페이스를 구현한 클래스가 아닌 경우 sort() 메소드를 호출하는 경우 다음과 같은 에러가 발생합니다.

    Comparable에 대해서는 뒤에서 더 자세히 설명하도록 하겠습니다.

     

     

     

    2. Collections.sort()

     

    배열의 원소를 정렬할 때는 Arrays.sort() 메소드를 사용하지만 ArrayList의 원소를 정렬하기 위해서는 Collections클래스의 sort() 메소드를 이용해서 정렬할 수 있습니다.

     

    static <T extends Comparable<? super T>> void sort(List <T> list)

    해당 리스트 원소 타입의 natural ordering에 따라 정렬

    static <T> void sort(List<T> list, Comparator <? super T> c)

    Comparator에 의해 정의된 기준에 의해 리스트를 정렬

    Collections 클래스는 sort() 메소드를 위와 같이 오버로딩하고 있습니다.

    전자의 sort() 메소드는 Comparable 인터페이스를 구현한 클래스로 타입을 제한한 리스트를 인자로 받습니다. 후자의 sort() 메소드는 리스트와 함께 Comparator를 받습니다.

     

     

     

    3. Comparable인터페이스

     

    여기서 Comparable 인터페이스에 대해 알아보겠습니다.

    Comparable 인터페이스에는 단 하나의 메소드가 존재하는데, 그것이 바로 compareTo() 메소드입니다.

    compareTo() 메소드는 정렬 기준을 결정하는 메소드로, 정렬을 위해서는 compareTo() 메소드가 정의되어있어야 합니다.

    즉, Comparable 인터페이스를 구현하지 않아 compareTo() 메소드를 갖고 있지 않은 클래스의 경우 natural ordering이 존재하지 않아 정렬이 불가능합니다.

     

    예시를 위해 name과 age라는 멤버 변수를 갖는 Student클래스를 생성했습니다.

    위와 같이 Student 타입의 배열을 생성한 후,  Arrays.sort() 메소드를 호출하니 다음과 같은 에러가 발생했습니다.

    Student 타입의 객체를 Comparable로 캐스팅할 수 없다는 내용인데요, sort() 메소드를 호출하면 해당 리스트의 원소를 Comparable로 캐스팅한 후 비교를 통해 정렬한다는 사실을 알 수 있습니다.

    단순히 생각해봐도 String타입과 int타입의 변수를 가지고 있는  Student 타입 객체를 어떤 기준으로 정렬해야 할지 모호합니다.

     

    그렇다면 Student 타입 리스트를 정렬하기 위해서는 어떻게 해야 할까요?

    compareTo() 메소드를 갖는 Comparable인터페이스를 구현한 클래스 타입으로 만들어주면 됩니다.

     

     

    Student 클래스를 위와 같이 수정했습니다.

    Comparable인터페이스를 구현했고, compareTo() 메소드를 오버 라이딩해, age를 기준으로 오름차순 정렬하도록 설정했습니다.

    동일하게 함수를 실행하면 위와 같이 age를 기준으로 오름차순 정렬된 것을 확인할 수 있습니다.

     

     

     

    4. Comparator 인터페이스

     

    그렇다면 Comparator 인터페이스의 역할은 무엇일까요?

    이미 Comparable 인터페이스를 구현한 클래스의 리스트를 다른 기준으로 정렬하고 싶을 때, Comparator를 사용합니다.

     

    sort() 메소드를 호출할 때, Comparator 인터페이스를 구현한 클래스를 인자로 넘기고, Comparator 인터페이스에 존재하는 comopare() 메소드를 오버라이딩 함으로써 정렬 기준을 정의합니다.

    String 타입의 배열을 sort() 하면 String클래스의 natural ordering에 따라 알파벳 기준으로 오름차순 정렬됩니다.

    그렇다면 이 배열을 각 원소의 문자열의 길이에 따라 내림차순 정렬하기 위해 Comparator 클래스를 이용해보겠습니다.

     

    sort() 메소드의 두 번째 인자로 Comparator를 익명 클래스로 구현해 넘겨주었습니다.

    Comparator내부에 compare() 메소드를 오버라이딩 하여 정렬 기준을 작성했습니다. 각 원소의 문자열 길이에 따라 내림차순 정렬하고, 문자열의 길이가 같은 경우에는 compareTo() 메소드를 이용해 String타입의 natural ordering에 따라 정렬되도록 했습니다.

     

    그 결과 문자열의 길이가 긴 순서대로 정렬되고, 문자열의 길이가 같은 Blueberry와 Tangerine의 경우 알파벳 오름차순에 따라 정렬되었음을 확인할 수 있습니다.

     

     

    'Language > Java' 카테고리의 다른 글

    [Java] Java의 컬렉션 프레임워크  (0) 2020.04.19
    [JAVA] Enum이란?  (0) 2020.03.15
    [JAVA] Reflection  (0) 2020.02.01
    [JAVA] Generic Type  (0) 2020.02.01
    [JAVA] Reader/Writer  (0) 2019.12.07
Designed by Tistory.