Comparator와 Comparable
모두 인터페이스로 컬렉션을 정렬하는데 필요한 메서드를 정의하고 있으며, Comparable을 구현하고 있는 클래스들은 같은 타입의 인스턴스끼리 비교할 수 있는 클래스들이며, 기본적으로 오름차순으로 정렬되도록 구현되어 있다.
알고리즘 문제를 풀 때 정렬 기준을 바꿔야 하는 경우가 많아 유용하게 쓰인다.
👉 Comparable: 기본 정렬기준을 구현하는 데 사용 (클래스의 기본 정렬 기준을 재정의하는 데 사용)
👉 Comparator: 기본 정렬 기준 외에 다른 기준으로 정렬하고자 할 때 사용 (클래스 단위가 아닌 객체마다 정렬 기준을 다르게 하는 데 사용)
실제 소스:
public interface Comparator{
int compare(Object o1, Object o2);
boolean equals(Object obj);
}
public interface Comparable{
public int compareTo(Object o);
}
Comparable 사용 예시
아래는 백준 1377 버블소트 소스 코드중 일부다. (전체코드)
class Point implements Comparable<Point>{
int value;
int index;
public Point(int value, int index) {
this.value = value;
this.index = index;
}
@Override
public int compareTo(Point o) { // value 기준 오름차순 정렬
return this.value - o.value;
}
}
compareTo의 정렬 기준
리턴 결과가 양수일 때 (this.value > o.value)
👉 매개변수로 들어온 o 객체가 더 작다고 판별되어 주체 객체와 대상 객체가 교체되어 정렬된다. (기본 정렬은 오름차순)
리턴 결과가 음수일 때 (this.value < o.value)
👉 매개변수로 들어온 o 객체가 더 크다고 판별되어 정렬을 유지한다.
리턴 결과가 0일 때 (this.value = o.value)
👉 매개변수로 들어온 o 객체와 값이 같다고 판별되어 정렬을 유지한다.
내림차순으로 정렬하려면 아래와 같이 return 문에서 순서만 바꾸면 된다.
@Override
public int compareTo(Point o) { // value 기준 내림차순 정렬
return o.value - this.value;
}
👉 Collections.sort(객체) 사용 시 대상 객체가 Comparable 인터페이스로 정의한 기준에 따라 정렬된다. 객체의 경우 정렬 기준을 정의하지 않고 Collections.sort(객체)를 사용하면 컴파일 에러가 난다.
Comparator 사용 예시
정렬 대상 클래스와 다른 기준으로 정렬할 경우 사용할 수 있다.
Comparator<Point> comparator = new Comparator<Point>(){
@Override
public int compareTo(Point o) { // index 기준 내림차순 정렬
return o.index - this.index;
}
}
Arrays.sort(points, comparator);
아래와 같이 합쳐서 작성할 수도 있다.
Arrays.sort(points, new Comparator<Point>(){
@Override
public int compareTo(Point o) { // index 기준 내림차순 정렬
return o.index - this.index;
}
});
int 배열도 Comparable을 구현한 클래스이기 때문에 아래와 같이 작성할 수 있다.
- 이차원 배열인 arr를 정렬
- 배열의 두 번째 값이 같은 경우에는 첫 번째 값으로 오름차순 정렬을 하고, 그렇지 않을 경우는 두 번째 값으로 오름차순 정렬을 한다.
Arrays.sort(arr, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
if (o1[1] == o2[1]) return o1[0] - o2[0];
return o1[1] - o2[1];
}
});
오름차순/내림차순, 첫 번째/두 번째 값 기준만 바꿔가면서 응용하면 알고리즘 문제를 풀 때 아주 유용하게 쓰이는 코드다.
참고:
자바의 정석 - 남궁성 p628-630
https://yuja-kong.tistory.com/entry/Java-%EA%B0%9D%EC%B2%B4-%EC%A0%95%EB%A0%AC-Comparable-Comparator
'JAVA' 카테고리의 다른 글
[JAVA] 전략 패턴을 이용해 런타임 중 알고리즘 선택 (0) | 2023.08.23 |
---|---|
[JAVA] 지네릭스(Generics) (0) | 2022.12.27 |
[JAVA] HashSet, TreeSet, 해싱 (0) | 2022.12.22 |
[JAVA] ArrayList vs LinkedList (0) | 2022.12.14 |
[JAVA] Collections Framework 인터페이스 (0) | 2022.12.12 |
댓글