어째서 매번 기억이 나지 않는게야...
Comparator vs Comparable을 매번 헷갈리고 구현해야하는 타이밍도 헷갈려한다
이게 맞나?
아무리 암기보단 이해를 우선시한다지만, 솔직히 다섯번 넘게 헷갈리고 틀렸으면 이건 외워야하는 것이 맞다고 본다
지금부터 외워보자
(1) 우선 짚고 넘어가야 할 기본 정보
Comparable과 Comparator는 모두 객체를 정렬하는 인터페이스(interface)이다
But, 사용방법과 목적이 다르다
(2) 그렇다면 둘의 차이점은?
Comparable과 Comparator의 역할은 비슷한 것 같은데 아래 내용을 두줄 요약하면 아래와 같다
- Comparable은 자기 자신과 매개변수 객체를 비교하는 것 (비교 기준 1개만 작성 가능, `int compareTo(T o)`)
- Comparator는 두 매개변수 객체를 비교하는 것 (비교 기준 1개 이상 작성 가능, `int compare(T o1, T o2)`)
(1) Comparable 인터페이스
- 객체 자체에 정렬 기준을 정의할 때 사용
- compareTo(T o) 메서드를 객체 내부에서 직접 구현해야 함
- 한 가지 정렬 기준만 정의 가능
사용 방법
- Comparable<T> 인터페이스를 구현하고, compareTo() 메서드를 오버라이딩
- Collections.sort(List<T>) 또는 Arrays.sort(T[]) 호출 시 자동으로 작성해둔 내용으로 적용
예시 코드 (정렬 기준을 `한개만` 작성할 수 있음)
더보기
import java.util.*;
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);
}
@Override
public String toString() {
return name + " (" + age + "세)";
}
}
public class ComparableExample {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 25));
people.add(new Person("Bob", 30));
people.add(new Person("Charlie", 22));
// 기본 정렬 (나이순)
Collections.sort(people);
System.out.println(people); // Charlie (22세), Alice (25세), Bob (30세)
}
}
정리 및 요약
- Comparable 사용 -> (클래스 자체에서) 정렬 기준 한가지 설정 가능
- Collections.sort 호출 시 작성해둔 compareTo() 기준으로 정렬됨
- 한 가지 기준만 가능 → 여러 기준으로 정렬하려면 Comparator 사용해야 함
(2) Comparator 인터페이스
- 객체 외부에서 정렬 기준을 정의할 때 사용
- compare(T o1, T o2) 메서드를 구현하여 정렬 기준을 여러 개 정의 가능
- Collections.sort(List<T>, Comparator<T>) 또는 List.sort(Comparator<T>) 사용
사용 방법
- Comparator<T> 인터페이스를 구현하여 별도 정렬 기준 생성
- 여러 정렬 기준을 만들 수 있어 유연하게 활용 가능
예시 코드 (정렬 기준을 `한개 이상` 작성할 수 있음)
더보기
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 + "세)";
}
}
// 나이 오름차순 정렬 Comparator
class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return Integer.compare(p1.age, p2.age);
}
}
// 이름 가나다순 정렬 Comparator
class NameComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
}
public class ComparatorExample {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 25));
people.add(new Person("Bob", 30));
people.add(new Person("Charlie", 22));
// 나이순 정렬
Collections.sort(people, new AgeComparator());
System.out.println("나이순: " + people); // Charlie (22세), Alice (25세), Bob (30세)
// 이름순 정렬
Collections.sort(people, new NameComparator());
System.out.println("이름순: " + people); // Alice (25세), Bob (30세), Charlie (22세)
}
}
정리 및 요약
- Comparator를 사용하면 클래스 외부에서 여러 개의 정렬 기준을 정의 가능
- Collections.sort(리스트, Comparator) 사용하여 다양한 기준으로 정렬 가능
- 정렬 기준을 변경할 수 있어 유연함 → 기본 정렬(Comparable)을 오버라이드하지 않고도 다른 기준 적용 가능
마치며
정리하고 든 생각은 `어중간하게 이해하고 있으면, 헷갈릴만 했다` 였다
그동안 어중간하게 알고 있었단 생각도 들었고...
내가 외울 것은 아래 내용의 구현 코드이다
Comparable - 클래스 내부에 작성
class Person implements Comparable<Person> {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Integer.compare 사용
@Override
public int compareTo(Person other) {
return Integer.compare(this.age, other.age); // 🔹 자기 자신(this)과 매개변수(other) 비교
}
// 또는 그냥 `-`비교 연산
@Override
public int compareTo(Person other) {
return this.age - other.age; // 🔹 자기 자신(this)과 매개변수(other) 비교
}
}
Comparator - 클래스 외부에 작성
class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return Integer.compare(p1.age, p2.age); // 🔹 두 개의 매개변수(p1, p2) 비교
}
}
'JAVA' 카테고리의 다른 글
Queue 구현 시, LinkedList보다 ArrayDeque를 추천하는 이유 (0) | 2025.03.07 |
---|