Java에서 Comparator로 문자열 리스트를 정렬할 수 있습니다. Comparator는 어떻게 정렬할지에 대한 내용이 구현되어있는 객체입니다. 이 객체를 리스트의 sort() 함수에 전달하면 Comparator의 규칙에 맞게 정렬됩니다.

Comparator

Comparator<T>는 함수형 인터페이스이고, compare() 메소드를 갖고 있습니다.

  • compare()는 인자 o1과 o2 객체를 비교하고 결과를 리턴

비교 결과는 음수, 0, 양수 중에 하나이며, 각각 의미는 다음과 같습니다. 비교 결과로 리스트를 정렬을 할 수 있습니다.

  • 음수 : o1이 o2보다 작음
  • 0 : o1과 o2와 같음
  • 양수 : o1이 o2보다 큼
@FunctionalInterface
public interface Comparator<T> {

    /**
     * Compares its two arguments for order.  Returns a negative integer,
     * zero, or a positive integer as the first argument is less than, equal
     * to, or greater than the second.
     *
     * @param o1 the first object to be compared.
     * @param o2 the second object to be compared.
     * @return a negative integer, zero, or a positive integer as the
     *         first argument is less than, equal to, or greater than the
     *         second.
     */
    int compare(T o1, T o2);
}

Comparator는 다음과 같이 구현하여 사용할 수 있습니다.

  • 클래스 파일을 만들고 구현을 추가할 수 있지만, 1회성으로 사용된다면 익명 클래스나, 람다식 또는 메소드 레퍼런스로 구현하여 인자로 전달함
  • List.sort(Comparator) 대신에 Collections.sort(List, Comparator)를 사용할 수도 있음
List<String> stringList = new ArrayList<>();
stringList.add("Apple");
stringList.add("Banana");
stringList.add("Cherry");

// 1) 익명 클래스로 구현
stringList.sort(new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return Integer.compare(s1.length(), s2.length());
    }
});

// 2) 람다식
stringList.sort((s1, s2) -> Integer.compare(s1.length(), s2.length()));

// 3) 메소드 레퍼런스(Method References)를 이용한 방법
stringList.sort(Comparator.comparingInt(String::length));

// 4) Collections.sort() 이용
Collections.sort(stringList, (s1, s2) -> Integer.compare(s1.length(), s2.length()));

Comparator로 문자열 리스트 정렬

아래 예제는 Comparator를 구현하여 문자열 리스트를 정렬합니다.

주석을 보면, 길이로 정렬하는 부분이 있는데, Integer.compare()로 길이를 비교하여 정렬합니다. 정렬 순서를 반대로 뒤집으면 오름차순 정렬이 내림차순 정렬로 됩니다.

  • 문자열을 길이로 오름차순 정렬
  • 문자열을 길이로 내림차순 정렬

또한, 알파벳 순서로 정렬하는 것도 있는데, String.compareTo()를 이용하여 문자열의 알파벳 순서로 비교합니다. 이것도 비교 순서를 반대로하여 역순으로 정렬할 수도 있습니다.

  • 문자열을 알파벳 순으로 정렬
  • 문자열을 알파벳 역순으로 정렬

만약 문자열을 다른 방식으로 정렬하고 싶다면, 직접 Comparator의 compare() 함수를 구현하시면 됩니다. 비교 결과에 따라서 음수, 0, 양수 값만 잘 리턴하면 됩니다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Example {

    public static void main(String[] args) {

        List<String> stringList = new ArrayList<>();
        stringList.add("Apple");
        stringList.add("Banana");
        stringList.add("Cherry");
        stringList.add("Date");
        stringList.add("Grape");

        // 문자열을 길이로 오름차순 정렬
        Collections.sort(stringList, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return Integer.compare(s1.length(), s2.length());
            }
        });
        System.out.println("문자열을 길이로 오름차순 정렬:");
        for (String str : stringList) {
            System.out.println(str);
        }

        // 문자열을 길이로 내림차순 정렬
        Collections.sort(stringList, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return Integer.compare(s2.length(), s1.length());
            }
        });
        System.out.println("\n문자열을 길이로 내림차순 정렬:");
        for (String str : stringList) {
            System.out.println(str);
        }

        // 문자열을 알파벳 순으로 정렬
        Collections.sort(stringList, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return s1.compareTo(s2);
            }
        });
        System.out.println("\n문자열을 알파벳 순서로 정렬:");
        for (String str : stringList) {
            System.out.println(str);
        }

        // 문자열을 알파벳 역순으로 정렬
        Collections.sort(stringList, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return s2.compareTo(s1);
            }
        });
        System.out.println("\n문자열을 알파벳 역순으로 정렬:");
        for (String str : stringList) {
            System.out.println(str);
        }
    }
}

Output:

문자열을 길이로 오름차순 정렬:
Date
Apple
Grape
Banana
Cherry

문자열을 길이로 내림차순 정렬:
Banana
Cherry
Apple
Grape
Date

문자열을 알파벳 순서로 정렬:
Apple
Banana
Cherry
Date
Grape

문자열을 알파벳 역순으로 정렬:
Grape
Date
Cherry
Banana
Apple

람다식, 메소드 레퍼런스를 이용하여 간단히 구현

위의 예제에서 Comparator 구현 방식을 람다식, 메소드 레퍼런스를 이용하면 더 짧은 코드로 동일한 내용을 구현할 수 있습니다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Example {

    public static void main(String[] args) {

        List<String> stringList = new ArrayList<>();
        stringList.add("Apple");
        stringList.add("Banana");
        stringList.add("Cherry");
        stringList.add("Date");
        stringList.add("Grape");

        // 문자열을 길이로 오름차순 정렬
        Collections.sort(stringList, Comparator.comparingInt(String::length));
        System.out.println("문자열을 길이로 오름차순 정렬:");
        for (String str : stringList) {
            System.out.println(str);
        }

        // 문자열을 길이로 내림차순 정렬
        Collections.sort(stringList, (s1, s2) -> Integer.compare(s2.length(), s1.length()));
        System.out.println("\n문자열을 길이로 내림차순 정렬:");
        for (String str : stringList) {
            System.out.println(str);
        }

        // 문자열을 알파벳 순으로 정렬
        Collections.sort(stringList, String::compareTo);
        System.out.println("\n문자열을 알파벳 순서로 정렬:");
        for (String str : stringList) {
            System.out.println(str);
        }

        // 문자열을 알파벳 역순으로 정렬
        Collections.sort(stringList, Comparator.reverseOrder());
        System.out.println("\n문자열을 알파벳 역순으로 정렬:");
        for (String str : stringList) {
            System.out.println(str);
        }
    }
}