Comparable과 Comparartor는 모두 인터페이스이다.
Comparable, Comparator를 사용하려면 인터페이스 내에 선언된 메소드를 구현해야 한다.
Comparable 인터페이스에는 CompareTo(T o)
메서드 하나가 선언되어 있다.
Comparator 인터페이스에서 우리가 실질적으로 구현해야 하는 것은
compare(T o1, T o2)
이다.
두 인터페이스의 역할은 객체를 비교할 수 있도록 만드는 것이다.
primitive type의 경우 (byte, int, double)등 부등호를 갖고 쉽게 두 변수를 비교할 수 있다.
반면에 객체는 사용자가 기준을 정해주지 않으면 비교할 수 없다.
Comparable과 Comparator의 차이는 Comparable의 CompareTo(T o)
는 매개변수가 한개다. 따라서 자기 자신과 매개변수 객체를 비교한다.
반면 Comparator는 compare(T o1, T o2)
로 두 매개변수 객체를 비교한다.
그리고 Comparable은 lang 패키지에 있어서 import 해줄 필요가 없다. Comparator는 util 패키지에 있어서 import를 해줘야 한다.
클래스를 만들 때 Comparable<Type>
을 implement 하게 하고 compareTo(Type o)
를 오버라이딩 해서 구현해주면 된다.
compareTo
를 통해 클래스를 비교하게 된다.
compareTo(Student o)
는 정수를 반환한다.
자기 자신을 기준으로 비교해야 한다.
즉 내가 더 크면 양수, 같으면 0, 작으면 음수를 반환한다.
public int compareTo(Student o) {
/*
* 만약 자신의 age가 o의 age보다 크다면 양수가 반환 될 것이고,
* 같다면 0을, 작다면 음수를 반환할 것이다.
*/
return this.age - o.age;
}
이렇게 구현하면 세가지를 한번에 해결할 수 있다.
다만 이렇게 -
로 리턴하는 방식을 사용하면 overflow 가 발생할 수도 있다. 따라서 primitive type에 대해서는 <,>,==
로 대소비교를 해주는 것이 안전하다.
Comparator는 두 매개변수 객체를 비교한다.
Comparator도 마찬가지로 implement 하고 구현해서 사용하면 된다.
public int compare(Student o1, Student o2) {
/*
* 만약 o1의 classNumber가 o2의 classNumber보다 크다면 양수가 반환 될 것이고,
* 같다면 0을, 작다면 음수를 반환할 것이다.
*/
return o1.classNumber - o2.classNumber;
}
Comparator를 사용하면 비교를 위해 객체를 하나 생성해야 한다는 단점이 있다.
이것을 해결하기 위해 익명 클래스를 활용할 수 있다.
익명 클래스는 이름이 정의되지 않은 객체이다.
익명 객체는 상속할 클래스나 인터페이스가 있어야 한다.
// 익명 객체 구현방법 1
Comparator<Student> comp1 = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.classNumber - o2.classNumber;
}
};
// 익명 객체 구현 2
public static Comparator<Student> comp2 = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.classNumber - o2.classNumber;
}
};
이렇게 익명 객체로 구현하면 클래스 내에 compare을 구현할 필요가 없다. 익명객체를 가리키는 comp를 통해 comp.compare(b,c)
와 같이 사용하면 된다.
Java에서 정렬은 특별히 정의가 되어 있지 않은 한 오름차순을 기준으로 한다.
Arrays.sort()
, Collections.sort()
모두 오름차순을 기준으로 한다.
compare이나 compareTo를 사용해 비교할 때
오름차순
// 자기 자신의 value을 기준으로 파라미터 값과의 차이를 반환한다.
@Override
public int compareTo(MyInteger o) {
return this.value - o.value;
}
내림차순
// Comparable
public int compareTo(MyClass o) {
return -(this.value - o.value);
}
// Comparator
public int compare(Myclass o1, MyClass o2) {
return -(o1.value - o2.value);
}
익명 클래스로 Comparartor를 구현한 comp
클래스를 만들고
Arrays.sort(array,comp)
로 정렬 기준을 정할 수 있다.