Comparable과 Comparator
객체 정렬에 필요한 메서드(정렬기준 제공)를 정의한 인터페이스
→ 정렬: 오름차순, 내림차순, 나이를 기준으로 정렬, 키를 기준으로 정렬, ...
- Comparable: 기본 정렬기준(default)을 구현하는 데 사용
→ 객체(o)와 자신(this)을 비교 - Comparator: 기본 정렬기준(default) 외에 다른 기준으로 정렬하고자 할 때 사용
- 0: 같다 (o1 = o2)
- 양수: 왼쪽이 크다 (o1 > o2)
- 음수: 오른쪽이 크다 (o1 < o2)
1
2
3
4
5
6
7
8
|
public interface Comparable {
int compareTo(Object o); //주어진 객체(o)를 자신(this)과 비교
}
public interface Comparator {
int compare(Object o1, Object o2); //o1, o2 두 객체를 비교
boolean equals(Object obj); //equals를 오버라이딩하라는 뜻
}
|
cs |
- compare()와 compareTo()는 두 객체의 비교결과를 반환하도록 작성
같으면 0, 오른쪽이 크면 음수(-), 작으면 양수(+)
1
2
3
4
5
6
7
8
9
10
11
|
public final class Integer extends Number implements Comparable {
...
public int compareTo(Integer anotherInteger) {
int v1 = this.value;
int v2 = anotherInteger.value;
//같으면 0, 오른쪽 값이 크면 -1, 왼쪽 값이 크면 1을 반환
return (v1 < v2 ? -1 : (v1 == v2? 0 : 1));
}
...
}
|
cs |
자리바꿈
- 오름차순: 7 > 5 => 5, 6, 7, 8, ...
- 내림차순: 5 < 7 => 7, 6, 5, 4, ...
정렬
- 정렬 대상 ex) strArr
- 정렬 기준 ex)String.CASE_INSENSITIVE_ORDER (대소문자 구분X) / new Descending() (역순 정렬)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class Ex11_7 {
public static void main(String[] args) {
String[] strArr = {"cat", "Dog", "lion", "tiger"};
Arrays.sort(strArr); //정렬대상 => String의 Comparable구현에 의한 정렬
System.out.println("strArr= " + Arrays.toString(strArr)); //사전순서(대문자 먼저)
Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); //정렬대상, 정렬기준(대소문자 구분X)
System.out.println("strArr= " + Arrays.toString(strArr));
Arrays.sort(strArr, new Descending()); //역순 정렬
System.out.println("strArr= " + Arrays.toString(strArr));
}
}
class Descending implements Comparator {
@Override
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을 곱해서 기본 정렬방식의 역으로 변경한다.
//또는 c2.compareTo(c1)과 같이 순서를 바꿔도 된다.
}
return -1;
}
}
|
cs |

Integer와 Comparable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public final class Integer extends Number implements Comparable {
...
public int compareTo(Object o) {
return compareTo((Integer)o);
}
public int compareTo(Integer anotherInteger) {
int thisVal = this.value;
int anotherVal = anotherInteger.value;
//비교하는 값이 크면 -1, 같으면 0, 작으면 1을 반환한다.
return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
//오른쪽 값이 크면 음수를, 두 값이 같으면 0, 왼쪽 값이 크면 양수를 반환한다.
return thisVal - anotherVal; //내림차순의 경우 반대로 뺄셈하면 된다.
}
...
}
|
cs |
Comparable의 compareTo 사용해보기
예제) 좌표 정렬하기
N개의 평면상의 좌표(x, y)가 주어지면 모든 좌표를 내림차순으로 정렬하는 프로그램을 작성하세요.
[입력]
첫째 줄에 좌표의 개수인 N(3<=N<=100,000)이 주어진다.
두 번째 줄부터 N개의 좌표가 x, y 순으로 주어진다. x, y 값은 양수만 입력된다.
[출력]
N개의 좌표를 정렬하여 출력하세요.
[예시]
아래 이미지 참조

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
package day02;
import java.util.*;
public class Q17_PointSort {
public static void main(String[] args) {
//x, y좌표를 갖는 Point 클래스를 구현하여 정렬하세요
//우선 x좌표를 내림차순 정렬하되, x값이 동일할 경우는 y값 내림차순으로 정렬하세요
Scanner scanner = new Scanner(System.in);
System.out.println("좌표의 개수를 입력하세요: ");
int num = scanner.nextInt();
ArrayList<Point> arr = new ArrayList<>(); //Point 객체를 담을 ArrayList
System.out.println("좌표(x, y)의 x, y값을 입력하세요: ");
for(int i = 0; i < num; i++) {
int x = scanner.nextInt();
int y = scanner.nextInt();
arr.add(new Point(x, y)); //ArrayList에 Point 객체를 생성하여 담기
}
//override한 compareTo의 정렬 기준에 따라 sort가 자동으로 정렬해준다.
Collections.sort(arr);
for(Point o:arr) {
System.out.println(o.getX() + " " + o.getY());
}
}
}
class Point implements Comparable<Point>{
private int x;
private int y;
public Point() {
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public int compareTo(Point o) {
if(this.x == o.x) { //x좌표의 값이 같으면 y좌표의 값으로 정렬
return o.y - this.y; //y좌표 내림차순
}else {
return o.x - this.x; //그 외 x좌표 내림차순
}
}
}
|
cs |
compareTo() 메서드는 개발자가 직접 호출하는 게 아니라 Comparable 인터페이스가 구현된 클래스 객체들이 담겨 있는 배열을 .sort()시 자동으로 호출되면서 각각의 객체들의 비교를 수행한다.
