[Java] Comparable vs Comparator
Comparable와 Comparator은 객체를 정렬할 때 입맛에 맞게 정렬하기 위해 사용한다. 각각의 인터페이스를 사용하는 방법에 차이가 있고 정렬하는 방식은 같다. 음수는 앞으로 가고 0은 제자리에 머물고 양수는 뒤로 간다는 것이다.
먼저 Comparable를 보면 클래스 안에서 implements 하여 compareTo 메소드를 재정의 하여 사용하는데 현재의 객체와 파라미터로 들어오는 객체를 비교한다.
class Example implements Comparable<Example> {
int a;
int b;
example(int a, int b){
this.a=a;
this.b=b;
}
public int compareTo(Example o) {
if(a > o.a){
return 1;
} else if(a < o.a) {
return -1;
} else {
if(b > o.b){
return -1;
} else if(b<o.b){
return 1;
} else {
return 0;
}
}
}
}
위와 같이 코딩하고 Collections.sort(List) 하면 우선 a를 비교하며 오름차순으로 정렬하다가 a가 같을 때는 b를 비교하여 내림차순으로 정렬되는 것을 볼 수 있다.
단 Comparable을 사용할 때에는 지켜야 할 규칙이 있다.
1. sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
2. x.compareTo(z) > 0 이고 z.compareTo(y) > 0 이면 y.compareTo(x) > 0 이여야 한다.
3. x.compareTo(y) == 0 이면 sgn(x.compareTo(z)) == sgn(y.compareTo(z)) 이여야 한다.
4. (x.compareTo(y)==0) == (x.equals(y))
마지막 4번은 지키는 것을 권장하지만 지키지 않아도 된다. 단 equals와 일치하지 않음을 나타내야 한다고 한다. (JavaDoc에 적혀있다.)
다음 Comparator를 보면 새로운 클래스에 implements 하여 사용하는 것이다.
class Example {
int a;
int b;
example(int a, int b){
this.a=a;
this.b=b;
}
}
위 클래스는 Comparable을 뺀 Example 클래스이다.
class comparator implements Comparator<example>{
public int compare(example o1, example o2) {
return o1.a-o2.a==0?o2.b-o1.b:o1.a-o2.a;
// 위의 compareTo메소드를 줄여봤다.
// 동작하는 내용은 같다.
}
}
위 클래스는 Comparator를 implements 하여 compare 메소드를 재정의한 클래스이다.
사용하는 방법은 간단하다. Collections.sort(List, new comparator()); 하면 된다.
Comparator을 사용할 때도 지켜야할 규칙이 있다.
1. sgn (compare (x, y)) == -sgn (compare (y, x))
2. ((compare (x, y)> 0) 이고 (compare (y, z)> 0)) 이면 compare (x, z)> 0 이여야 한다.
3. compare (x, y) == 0 이면 sgn (compare (x, z)) == sgn (compare (y, z)) 이여야 한다.
4. (compare (x, y) == 0) == (x.equals (y))
마지막 4번은 지키는 것을 권장하지만 지키지 않아도 된다. 단 equals와 일치하지 않음을 나타내야 한다고 한다. (JavaDoc에 적혀있다.)