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 |