Comparator

2024-05-12

Comparator로 정렬하기

자바 List, Collection API에는 기본적으로 sort 메서드가 포함되어있다.

이번엔 다양한 요구사항에 대응할 수 있는 정렬을 수행할 수 있게 Comparator를 구현 후 comparator 객체를 이용해 기본 sort의 파라미터화 해서 sort 메서드 동작을 커스텀해보자!

@FunctionalInterface
public interface Comparator<T> {
		int compare(T o1, T o2);
...
}

Comparator의 compare 메서드를 사용하여 구현해보겠다.

record User(String name, Integer age) {}

myList.sort((User obj1, User obj2) -> obj1.age().compareTo(obj2.age()));

이렇게 간단하게 구현하여 User 객체 안의 age를 비교하여 정렬을 할 수 있다.

형식을 추론하여

record User(String name, Integer age) {}

myList.sort((obj1, obj2) -> obj1.age().compareTo(obj2.age()));

로 코드를 개선할 수 있다.

비교적 어려운 정렬

@Getter
public class Content {
    private String index;
    private String title;
    private String detail;

}
    private static final Comparator<Content> customComparator = (c1, c2) -> {
        if (c1 == null && c2 == null) {
            return 0;
        } else if (c1 == null) {
            return -1;
        } else if (c2 == null) {
            return 1;
        }

        String[] index1 = c1.getIndex().split("\\.");
        String[] index2 = c2.getIndex().split("\\.");

        for (int i = 0; i < Math.max(index1.length, index2.length); i++) {
            int part1 = i < index1.length ? Integer.parseInt(index1[i]) : 0;
            int part2 = i < index2.length ? Integer.parseInt(index2[i]) : 0;

            if (part1 != part2) {
                return part1 - part2;
            }
        }

        return 0;
    };

대마위키의 코드 중 하나이다.

위 코드에서 직접 Comparator 객체를 람다 표현식을 사용하여 생성 후 sort 메서드의 파라미터화 하여 정렬을 하고 있는 로직이다.

요구사항이 목차의 인덱스 값은 String으로 되어있고 숫자 사이에 점을 사용하여 나타내는 것*(예 1.1.2, 2.3)*을 정렬하는 것이였다.

먼저 1.1.1을 . 을 기준으로 문자열을 분리하여 배열에 저장하고 그 배열을 for문, if문을 사용하여 비교하는 Comparator 객체이다.

예시

일 때 인덱스를 분리하면 [1, 2, 3]과 [1, 2, 4]이 된다.

1.2 부분은 같으므로 패스한다. 마지막 부분에서 3, 4로 차이가 나는데

3 - 4 = -1을 반환하여 객체1이 객체2 앞에 가게된다. 이 정렬에서는 양수와 음수 0으로 구분하여 객체끼리의 정렬이 완료된다.