[Java] Comparable vs Comparator
1. Comparable이란?
- 객체 내부에 정렬 기준을 직접 구현
- 자기 자신이 "나는 이렇게 정렬될 거야"라고 말하는 구조
compareTo()
메서드 오버라이딩
class Person implements Comparable<Person> {
String name;
int age;
@Override
public int compareTo(Person o) {
return this.age - o.age; // 나이 오름차순
}
}
2. Comparator란?
- 외부에서 정렬 기준을 따로 정의
- 여러 기준으로 정렬하거나, 기존 클래스를 수정할 수 없을 때 유용
- 익명 클래스나 람다식으로 간결하게 구현 가능
// 이름 기준 오름차순
Comparator<Person> byName = (p1, p2) -> p1.name.compareTo(p2.name);
// 나이 기준 내림차순
Comparator<Person> byAgeDesc = Comparator.comparingInt((Person p) -> p.age).reversed();
3. Comparator 체이닝 (복합 정렬)
정렬 기준이 여러 개일 경우, 체이닝으로 묶을 수 있다.
// 회원 목록을 최근 로그인순 → 나이 내림차순 → 이름 오름차순 정렬
Comparator<Member> memberComparator = Comparator
.comparing(Member::getLastLogin).reversed()
.thenComparing(Member::getAge, Comparator.reverseOrder())
.thenComparing(Member::getName);
list.sort(
Comparator.comparing(Person::getAge) // 나이 오름차순
.thenComparing(Person::getName) // 나이가 같으면 이름순
);
4. Arrays.sort vs Collections.sort
메서드 | 내부 정렬 방식 | 특징 |
---|---|---|
Arrays.sort | DualPivotQuickSort / TimSort | 기본형 배열 정렬 |
Collections.sort | TimSort (Java 7+) | List 계열 정렬, 안정 정렬(stable sort) |
5. Stream에서도 정렬 가능
List<Person> sorted = people.stream()
.sorted(Comparator.comparing(Person::getAge).reversed()
.thenComparing(Person::getName))
.collect(Collectors.toList());
6. 언제 무엇을 써야 할까?
Comparable
vs Comparator
비교
항목 | Comparable | Comparator |
---|---|---|
정의 위치 | 객체 자신이 직접 정렬 기준을 정의 ( | 외부에서 정렬 기준을 정의 ( |
사용 목적 | 기본 정렬 기준을 정의할 때 | 다양한 정렬 기준을 따로 정의할 때 |
인터페이스 |
|
|
구현 방식 |
|
|
장점 | 코드 간결, 객체 자체 기준 | 유연한 다중 기준, 정렬 기준 변경 쉬움 |
단점 | 하나의 정렬 기준만 정의 가능 | 익명 클래스나 람다 써야 해서 코드 길어질 수 있음 |
7. 실무에서 성능 차이?
- 두 방식 모두 TimSort 기반이라 성능은 거의 동일하다. 정렬 속도 자체에는 차이가 없다.
- 성능보단 유연성과 구조의 차이이다. 실무에서는 보통 Comparator + 람다식 조합이 자주 쓰인다고 한다.
- 성능은 비슷하지만, 유지보수성과 유연성에서
Comparator
가 더 유리하기 때문이다. compareTo
와compare()
는 절대==
을 피하고Integer.compare()
또는Double.compare()
를 사용하는 게 안전하다.
상황 | 많이 쓰는 방식 |
---|---|
정렬 기준이 딱 하나일 때 |
|
다양한 정렬 기준이 필요한 리스트 (정렬 옵션 버튼) |
|
정렬 기준이 자주 바뀌거나 동적일 때, 라이브러리 |
|
복합 정렬 (날짜, 우선순위 등) |
|