Comparable Interface vs Comparator Interface
객체를 정렬한다는 것은 사용자가 정의한 기준으로 정렬하는 것이다.
객체를 비교하는 정렬 기준을 Comparable과 Comparator 인터페이스로 명시할 수 있다.
Comparable과 Comparator은 모두 인터페이스다.
인터페이스에 선언된 메소드를 구현하면서 사용자가 정렬 기준을 만든다는 것이다.
Interface Comparable
- compareTo(T o)가 선언되어 있다. -> 이 메소드를 오버라이드해서 사용한다.
- 자기 자신과 매개변수 객체를 비교한다.
java.lang
패키지 소속이다. import할 필요가 없다.
Comparable 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ClassName implements Comparable<Type> {
/*
...
code
...
*/
// 필수 구현 부분
@Override
public int compareTo(Type o) {
/*
비교 구현
*/
}
}
type에는 해당 클래스와 비교하고자하는 객체의 타입이 들어간다.
- compareTo 메소드의 리턴값이
- 양수일 때 : 자기자신이 비교대상 파라미터보다 크다
- 0 일 때 : 동일하다
- 음수일 때 : 자기자신이 비교대상 파라미터보다 작다
- 따라서 메소드를 구현할 때
Comparable를 이용해 정렬한 예시 코드
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Sort10825 {
static StringBuilder sb = new StringBuilder();
static FastReader scan = new FastReader();
static class Elem implements Comparable<Elem> {
public String name;
public int korean, english, math;
@Override
public int compareTo(Elem other) {
if (korean != other.korean) return other.korean - korean;
if (english != other.english) return english - other.english;
if (math != other.math) return other.math - math;
return name.compareTo(other.name);
}
}
static int N;
static Elem[] a;
static void input() {
N = scan.nextInt();
a = new Elem[N];
for (int i = 0; i < N; i++) {
a[i] = new Elem();
a[i].name = scan.next();
a[i].korean = scan.nextInt();
a[i].english = scan.nextInt();
a[i].math = scan.nextInt();
}
}
static void pro() {
Arrays.sort(a);
for (int i = 0; i < N; i++) {
sb.append(a[i].name).append('\n');
}
System.out.println(sb.toString());
}
public static void main(String[] args) {
input();
pro();
}
static class FastReader {
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public FastReader(String s) throws FileNotFoundException {
br = new BufferedReader(new FileReader(new File(s)));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}
여기서
1
2
3
4
5
6
7
8
9
10
11
12
13
static class Elem implements Comparable<Elem> {
public String name;
public int korean, english, math;
@Override
public int compareTo(Elem other) {
if (korean != other.korean) return other.korean - korean;
if (english != other.english) return english - other.english;
if (math != other.math) return other.math - math;
return name.compareTo(other.name);
}
}
이 부분이 Comparable을 상속하고 있다.
Interface Comparator
- compare(T o1, T o2)가 선언되어있다. -> 이 메소드를 오버라이드해서 사용한다.
- 두 매개변수 객체를 비교한다. 자기 자신과 상관없이 파라미터로 들어오는 두 객체를 비교햔다.
java.util
패키지 소속이다.
Comparator 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.Comparator; // import 필요
public class ClassName implements Comparator<Type> {
/*
...
code
...
*/
// 필수 구현 부분
@Override
public int compare(Type o1, Type o2) {
/*
비교 구현
*/
}
}
Comparator를 이용해 정렬한 예시 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Comparator;
public class Ex {
public static void main(String[] args) {
public static Comparator<Cat> comp1 = new Comparator<Cat>() {
@Override
public int compare(Cat o1, Cat o2) {
return o1.age - o2.age;
}
}
};
}
class Cat {
int age;
int weight;
Cat(int age, int weight) {
this.age = age;
this.weight = weight;
}
}
이 부분이 익명객체를 활용한 부분이다.
- 익명객체 : 이름이 정의되지 않은 객체
- 익명객체는 보통 인스턴스를 생성할 때
Cat c = new Cat();
라고 쓰는 것과 달리Cat c = new Cat(){구현부};
로 쓴다. - comp1 익명객체는 Ex를 상속받은 하나의 새로운 클래스를 만든 것이다.
reference
[Java] Comparable와 Comparator의 차이와 사용법
자바 [JAVA] - Comparable 과 Comparator의 이해