정의
// Integer class
public final class Integer extends Number implements Comparable<Integer> { ... }
// String class
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { ... }
구현 방법
- 정렬할 객체에 Comparable interface를 implements 후, compareTo() 메서드를 오버라이드하여 구현한다.
- compareTo() 메서드 작성법
- 현재 객체 < 파라미터로 넘어온 객체: 음수 리턴
- 현재 객체 == 파라미터로 넘어온 객체: 0 리턴
- 현재 객체 > 파라미터로 넘어온 객체: 양수 리턴
- 음수 또는 0이면 객체의 자리가 그대로 유지되며, 양수인 경우에는 두 객체의 자리가 바뀐다.
사용 방법
- Arrays.sort(array)
- Collections.sort(list)
참고 Arrays.sort()와 Collections.sort()의 차이
Arrays.sort()
- 배열 정렬의 경우
- Ex) byte[], char[], double[], int[], Object[], T[] 등 * Object Array에서는 TimSort(Merge Sort + Insertion Sort)를 사용
- Object Array: 새로 정의한 클래스에 대한 배열 * Primitive Array에서는 Dual Pivot QuickSort(Quick Sort + Insertion Sort)를 사용
- Primitive Array: 기본 자료형에 대한 배열
Collections.sort()
- List Collection 정렬의 경우
- Ex) ArrayList, LinkedList, Vector 등 * 내부적으로 Arrays.sort()를 사용
Comparable interface를 이용한 Java 객체를 정렬
// x좌표가 증가하는 순, x좌표가 같으면 y좌표가 감소하는 순으로 정렬하라.
class Point implements Comparable<Point> {
int x, y;
@Override
public int compareTo(Point p) {
if(this.x > p.x) {
return 1; // x에 대해서는 오름차순
}
else if(this.x == p.x) {
if(this.y < p.y) { // y에 대해서는 내림차순
return 1;
}
}
return -1;
}
}
// main에서 사용법
List<Point> pointList = new ArrayList<>();
pointList.add(new Point(x, y));
Collections.sort(pointList);
정의
compare() 메서드 작성법
- 첫 번째 파라미터로 넘어온 객체 < 두 번째 파라미터로 넘어온 객체: 음수 리턴
- 첫 번째 파라미터로 넘어온 객체 == 두 번째 파라미터로 넘어온 객체: 0 리턴
- 첫 번째 파라미터로 넘어온 객체 > 두 번째 파라미터로 넘어온 객체: 양수 리턴
- 음수 또는 0이면 객체의 자리가 그대로 유지되며, 양수인 경우에는 두 객체의 자리가 변경된다.
- 즉, Integer.compare(x, y)(오름차순 정렬)와 동일한 개념이다.
- return (x < y) ? -1 : ((x == y) ? 0 : 1);
- 내림차순 정렬의 경우 두 파라미터의 위치를 바꿔준다.
- Integer.compare(y, x)(내림차순 정렬)
사용 방법
- Arrays.sort(array, myComparator)
- Collections.sort(list, myComparator)
- Arrays.sort(), Collections.sort() 메서드는 두 번째 인자로 Comparator interface를 받을 수 있다.
참고 두 번째 인자로 Comparator interface를 받는 경우
우선 순위 큐(PriorityQueue) 생성자의 두 번째 인자로 Comparator interface를 받을 수 있다.
- PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
- 지정된 Comparator의 정렬 방법에 따라 우선 순위를 할당한다.
Comparator interface를 이용한 Java 객체를 정렬
// x좌표가 증가하는 순, x좌표가 같으면 y좌표가 감소하는 순으로 정렬하라.
class MyComparator implements Comparator<Point> {
@Override
public int compare(Point p1, Point p2) {
if (p1.x > p2.x) {
return 1; // x에 대해서는 오름차순
}
else if (p1.x == p2.x) {
if (p1.y < p2.y) { // y에 대해서는 내림차순
return 1;
}
}
return -1;
}
}
// main에서 사용법
List<Point> pointList = new ArrayList<>();
pointList.add(new Point(x, y));
MyComparator myComparator = new MyComparator();
Collections.sort(pointList, myComparator);
Comparator와 Comparable은 모두 인터페이스로 컬렉션을 정렬하는데 필요한 메서드를 정의하고있다.
Comparable을 구현하고 있는 클래스들은 같은 타입의 인스턴스끼리 서로 비교할 수 있는 클래스들, 주로 Integer와 같은 wrapper 클래스와 String, Date, File과 같은 것들이며, 기본적으로 오름차순으로 정렬하게 되어있다.
compareTo()의 반환값은 int지만 실제로는 비교하는 두 객체가 같으면 0, 비교하는 값보다 작으면 음수, 크면 양수를 반환하도록 구현해야 한다. 이와 마찬가지로 compare()도 객체를 비교해서 음수, 0, 양수중의 하나를 반환하도록 구현해야한다.
Comparable을 구현한 클래스들이 기본적으로 오름차순으로 정렬되어 있지만, 내림차순으로 정렬한다던가 아니면 다른 기준에 의해서 정렬되도록 하고 싶을 때 Comparator를 구현해서 정렬기준을 제공할 수 있다.
class ComparatorEx { public static void main(String[] args) { String[] strArr = {"cat", "Dog", "lion", "tiger"}; Arrays.sort(strArr); //String의 Comparable 구현에 의한 정렬 Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); //대소문자 구문 안함 Arrays.sort(strArr, new Descending()); //역순 정렬 } }
class Descending implements Comparator { public int compare(Object o1, Object o2) { if (o1 instanceof Comparable && o2 instanceof Comparable) { Comparable c1 = (Comparable)o1; Comparable c2 = (Comparable)o2; return c1.compareTo(c2) * -1; //-1을 곱해서 역정렬 } return -1; } }
감사합니다.
도움이 많이 되었습니다.