Comparable과 Comparator 은 둘 다 인터페이스(interface)이므로, 내부에 선언된 메소드를 구현해야 사용할 수 있다.
[Comparable]
Comparable를 살펴보면 내부에 compareTo(T o)만 Override 해주면 된다.
https://docs.oracle.com/javase/8/docs/api/
Java Platform SE 8
docs.oracle.com
[Comparator]
Comparator를 살펴보면 내부에 많은 메서드들이 있지만 compare(T o1, T o2)만 Override된다.
나머지 메서드들은 전부 기본구현(default 메서드)이 제공된다.
equals(Object obj)는 default 메서드는 아니지만 Object에서 상속받으므로 구현 하지 않아도 된다.
https://docs.oracle.com/javase/8/docs/api/
Java Platform SE 8
docs.oracle.com
Comparator vs Comparable!
1. 기본 개념
Comparable | Comparator | |
정의 | 객체 자기 자신이 비교 기준을 가짐 | 외부에서 비교 기준을 따로 정의 |
패키지 | java.lang (기본 제공) | java.util (추가 필요) |
메서드 | int compareTo(T o) | int compare(T o1, T o2) |
비교 기준 위치 | 클래스 내부 (this와 o를 비교) | 클래스 외부 (o1과 o2를 비교) |
사용 목적 | 객체 자체가 "나 이런 기준으로 정렬돼!" 라고 주장할 때 | 외부에서 여러 개의 정렬 기준을 적용할 때 |
장점 | 기본 정렬 기준을 클래스에 직접 넣을 수 있음 | 여러 정렬 기준을 유연하게 설정 가능 |
단점 | 한 가지 기준만 가능 | 코드가 살짝 더 길어질 수 있음 |
2. 사용 방법
(1) Comparable - 같은 클래스 끼리 비교
class Person implements Comparable<Person> {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person other) {
return Integer.compare(this.age, other.age); // 나이 오름차순 정렬
}
}
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Collections.sort(people); // 자동으로 compareTo 적용!
장점: 객체 자체가 비교 기준을 가지므로 sort() 호출만으로 정렬이 가능!
단점: 정렬 기준을 하나밖에 정의할 수 없음. (ex. 이름으로 정렬하려면 새로운 방법 필요)
(2) Comparator - 다른 클래스와도 비교 가능 (외부에서 정렬 기준 제공)
사용방법:
- 인터페이스 구현 방식
import java.util.*;
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + " (" + age + ")";
}
}
// 나이 기준 오름차순 정렬
class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return Integer.compare(p1.age, p2.age);
}
}
public class ComparatorExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
);
Collections.sort(people, new AgeComparator());
System.out.println(people); // [Bob (25), Alice (30), Charlie (35)]
}
}
- 익명 클래스 사용
클래스를 따로 만들 필요 없이 익명 클래스로 바로 사용할 수도 있습니다.
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return Integer.compare(p1.age, p2.age);
}
});
- 람다식 사용
people.sort((p1, p2) -> Integer.compare(p1.age, p2.age));
//comparing사용
people.sort(Comparator.comparing(p -> p.age));
//::사용 (제일 깔끔하고 이해하기도 좋아보인다)
people.sort(Comparator.comparing(Person::age));
(2-1) 기능
//reversed(): 오름차순을 내림차순으로 변경 가능.
people.sort(Comparator.comparing(Person::getAge).reversed());
//comparing,thenComparing 나이가 같다면 이름순으로 정렬 가능.
people.sort(Comparator.comparing(Person::getAge).thenComparing(Person::getName));
3. 정리
- 객체 자체가 정렬 기준을 가지는 게 적절하면 Comparable 사용.
- 비교 기능을 외부로 빼기, 다중 정렬은 Comparator를 사용.
반응형
'Language > JAVA' 카테고리의 다른 글
@Retension (SOURCE,CLASS,RUNTIME) (0) | 2025.03.14 |
---|