Comparable, Comparator를 이용한 정렬
Comparable , Comparator
: 우선 둘 모두 인터페이스이다.
즉, 둘 모두 인터페이스 내에 선언된 메소드를 반드시 구현해야 한다.
: Comparable
compareTo(T o) 메소드 하나가 선언되어 있다.
: Comparator
여러 메소드가 있지만 실질적으로는, compare(T o1,T o2)를 구현해야한다.
: 추가로 Comparator에 여러 메소드가 있지만, 하나만 구현해도 되는 이유는
Java8부터 interface에 일반 메소드를 구현할 수 있도록 변경되었다. default나 static으로 선언된 메소드는 일반 메소드로 구현할 수 있다.
물론 default나 static으로 선언되지 않았어도 상위 타입에서 정의된 메소드가 있는경우 구현이 강제되지 않는다.
: 이러한 compareTo 혹은 compare 메소드는 어떤 때 사용하면 좋을까
기본적으로 자바에서 제공하는 primitive type은 부등호등으로 쉽게 비교가 가능하지만,
새로운 클래스 객체를 만들어 비교하게 된다면 좀 다른 기능의 비교메소드가 있어야 편리하다.
: 여기에는 복잡한 부분이 없어서 코딩으로 보여드리겠다.
중간에 사용된 익명객체에대해 잘 모른다면
https://the-bingle.tistory.com/76 이 포스트를 보고 오시거나 구글에 익명객체를 검색해보시는 것을 추천한다.
이 내용은 기본적인 두 인터페이스의 활용이다.
Java의 일반적인 정렬기준은 오름차순이 기준이 된다.
compare, compareTo 에서 보았듯,
두 값의 비교를 할때, 1과 3을 비교한다면 1 - 3으로 -2음수가 나올 것이다.
즉, 오름차순 베이스일때는 compare, compareTo를 사용하여 비교할 경우 음수가 나오면 두 원소의 위치를 바꾸지 않는다.
당연히 반대의 경우에는 원소의 위치를 바꾼다.
두 수의 비교 결과에 따른 작동방식을 지정할 수 있게된다.
1. 음수일 경우 : 두 원소의 위치를 교환안함
2. 양수일 경우 : 두 원소의 위치를 교환
정렬을 구현해보면 Counting Sort 같은 특수한 경우를 제외하고
Insertion, Quick, Merge 등 다양한 정렬 알고리즘은
'두 데이터(요소)의 비교'를 통해 두 원소를 교환할지 말지를 정하게 된다고 한다.
( 아직 위 정렬중에 구현해본것이 없다.. 배울게 넘나 많구만 )
간단한 Arrays.sort()를 이용해서 정렬하는 코드를 짜보았다.
이 전까지는 Arrays.sort()에서 지원하는 타입들만 정렬이 가능한지 알았는데,
좀 실용적으로 활용하는 방법을 배웠다.
import java.util.Arrays;
import java.util.Comparator;
public class SortTest {
public static void main(String[] args) {
MInt[] arr = new MInt[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = new MInt((int)(Math.random()*100));
}
System.out.print("정렬 전 : ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i].value + " ");
}
System.out.println();
Arrays.sort(arr);
System.out.print("정렬 후 : ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i].value + " ");
}
System.out.println();
System.out.println("======================");
YInt[] arr2 = new YInt[10];
for (int i = 0; i < arr2.length; i++) {
arr2[i] = new YInt((int)(Math.random()*100));
}
System.out.print("정렬 전 : ");
for (int i = 0; i < arr2.length; i++) {
System.out.print(arr2[i].value+" ");
}
System.out.println();
// Arrays.sort(arr2);
//
// System.out.print("정렬 후 : ");
// for (int i = 0; i < arr2.length; i++) {
// System.out.print(arr2[i].value+" ");
// }
// System.out.println();
// Arrays.sort() 메소드가 compareTo를 이용해 정렬하기 때문에 compare을 사용하는 클래스는 정렬할 수 없다.
// compare을 이용해서 정렬하려면 추가적인 코딩이 필요하다.
Arrays.sort(arr2, comp);
System.out.print("정렬 후 : ");
for (int i = 0; i < arr2.length; i++) {
System.out.print(arr2[i].value+" ");
}
System.out.println();
}
static class MInt implements Comparable<MInt>{
int value;
public MInt(int value) {
this.value = value;
}
@Override
public int compareTo(MInt m) {
return this.value - m.value;
}
}
static Comparator<YInt> comp = new Comparator<YInt>() {
@Override
public int compare(YInt y1, YInt y2) {
return y1.value - y2.value;
}
};
static class YInt {
int value;
public YInt(int value) {
this.value = value;
}
}
}
이로써 내가 만든 클래스도 정렬을 손쉽게 할 수 있을것이다.