1. Comparator와 Comparable의 차이점
Comparator: 객체의 외부에서 두 객체를 비교할 때 사용됩니다. 주로 여러 기준으로 객체를 정렬할 필요가 있을 때 유용합니다.Comparable: 클래스 자체에서 비교 기준을 정의하며,compareTo()메서드를 오버라이드하여 기본 정렬 방식을 제공합니다.Comparable을 구현하면 기본 정렬이 가능하지만, 필요할 때마다 정렬 기준을 다르게 적용하려면Comparator를 사용하는 것이 좋습니다.
2. 메서드 체이닝으로 다중 조건 정렬
Comparator를 사용하면 메서드 체이닝을 통해 다중 조건을 쉽게 설정할 수 있습니다. 예를 들어, 나이를 기준으로 정렬한 후 이름을 기준으로 다시 정렬하려면 thenComparing() 메서드를 활용할 수 있습니다.
여기서, 메서드 체이닝이란 연속적인 코드 줄에서 개체의 메서드를 반복적으로 호출하는것을 의미한다.
예제: 아래 코드는 나이로 먼저 정렬하고, 나이가 같은 경우 이름으로 추가 정렬합니다.
Arrays.sort(arr, Comparator.comparingInt(s -> Integer.parseInt(s[0]))
.thenComparing(s -> s[1]));
3. 역순 정렬
Comparator에는 기본적으로 제공되는 reversed() 메서드를 사용하여 손쉽게 정렬 순서를 뒤집을 수 있습니다. 예를 들어, 나이순 정렬에서 내림차순으로 변경하려면 다음과 같이 할 수 있습니다.
Arrays.sort(arr, Comparator.comparingInt(s -> Integer.parseInt(s[0])).reversed());
4. null 처리
정렬할 때 null 값이 포함될 수 있는 경우 Comparator.nullsFirst() 또는 Comparator.nullsLast()를 사용하여 null 값을 처리할 수 있습니다.
예제: null 값이 있는 배열을 처리하고, null을 가장 앞에 오도록 정렬합니다.
Arrays.sort(arr, Comparator.comparingInt(s -> Integer.parseInt(s[0]), Comparator.nullsFirst(Integer::compareTo)));
5. Primitive Type을 위한 Comparator (성능 최적화)
- 자바 8에서 도입된
comparingInt(),comparingLong(),comparingDouble()과 같은 메서드는 오토박싱을 피하고 기본형 타입에 직접 접근할 수 있어 성능 최적화가 가능합니다. - 이런 방식은 대량의 데이터를 다룰 때 유리하며, 특히 컬렉션이나 배열에 기본형 타입을 저장하고 정렬할 때 유용합니다.
6. Comparator에서 람다 표현식 사용
람다 표현식을 사용하면 Comparator를 보다 간결하고 명확하게 작성할 수 있습니다. 예를 들어, 다음과 같은 코드가 있을 때:
Arrays.sort(arr, (a, b) -> Integer.parseInt(a[0]) - Integer.parseInt(b[0]));
이 코드를 람다와 comparingInt로 변환하면 아래와 같이 더 직관적이고 간결하게 표현할 수 있습니다:
Arrays.sort(arr, Comparator.comparingInt(a -> Integer.parseInt(a[0])));
람다와 메서드 참조는 자바 8 이상에서 Comparator와 함께 자주 사용되는 패턴으로, 복잡한 비교 로직을 훨씬 읽기 쉽게 만들어준다.
7. 병렬 정렬 (parallelSort)
자바 8에서는 다중 코어를 활용해 성능을 극대화할 수 있는 Arrays.parallelSort() 메서드를 제공합니다. 이 메서드는 내부적으로 병렬 처리를 통해 정렬 성능을 향상시키므로, 큰 데이터셋을 다룰 때 성능 향상에 도움이 됩니다.
Arrays.parallelSort(arr, Comparator.comparingInt(s -> Integer.parseInt(s[0])));
단, 이 방식은 멀티코어 시스템에서만 이점이 있으므로 데이터 크기와 상황에 따라 사용을 고려해야 합니다.
8. Stream과 함께 사용하는 Comparator
자바 8의 Stream API와 Comparator를 함께 사용하면 매우 유연한 정렬을 구현할 수 있습니다. sorted() 메서드에 Comparator를 전달하여 스트림에서 정렬된 데이터를 얻을 수 있습니다.
List<String[]> sortedList = Arrays.stream(arr)
.sorted(Comparator.comparingInt(s -> Integer.parseInt(s[0])))
.collect(Collectors.toList());
이 코드는 배열을 스트림으로 변환한 후, 정렬한 다음 리스트로 변환합니다.
9. 성능 테스트
Comparator와 관련한 성능을 확인할 때는 데이터의 크기와 사용 환경에 따라 성능 차이가 발생할 수 있습니다. 예를 들어, 작은 데이터셋에서는 기본 정렬과 병렬 정렬의 성능 차이가 미미할 수 있지만, 대규모 데이터셋에서는 병렬 정렬이 큰 이점을 제공합니다. 이를 고려한 성능 테스트를 함께 작성하면 블로그에 실질적인 도움을 줄 수 있습니다.
요약
Comparator는 자바에서 매우 중요한 정렬 도구로, 단일 조건뿐 아니라 다중 조건, null 처리, 람다 활용 등 다양한 기능을 제공한다. 정렬 도구를 효과적으로 사용 할 수 있다는 점에서 자세히 알 필요가 있다고 생각한다.
'JAVA' 카테고리의 다른 글
| [JAVA] 오토 박싱과 오토 언박싱이란? (1) | 2024.09.13 |
|---|---|
| [JAVA] Abstract Class(추상 클래스)와 Interface (인터페이스) (0) | 2024.07.11 |