백준 문제를 풀다가 문자열 정렬이 나와 comparable과 comparator 공부를 하게 되었다.그래서 comparable과 comparator의 정확한 개념은 구글링을 해도 많이 나오기 때문에 나는 알고리즘 문제를 풀면서 적용할 수 있게끔, 나중에 내가 다시 봐도 이해할 수 있게 글을 써보았다.
comparator<T> 인터페이스
백준 문제를 풀다가 문자열 정렬이 나와 comparable과 comparator 공부를 하게 되었다. comparator은 java.util 패키지에 포함되어 있는 인터페이스이다. comparator는 comparable과 다르게 일반적인 기준이 아닌 특정 기준을 사용할 때 필요하다. comparator의 메소드는 compare(<T> o1, <T> o2)이다.
comparator<T> 활용
나는 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
|
public class Main {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
StringBuilder sb = new StringBuilder();
List<String> list = new ArrayList<>();
list.add("abc");
list.add("a");
list.add("abcd");
Comparator<String> c = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.length() - o1.length();
}
};
Collections.sort(list, c);
for(String str : list)
System.out.println(str);
}
}
|
cs |
comparator를 익명 클래스로 이용하여 구현했다. 이 부분이 중요한 것이 아니라, compare부분을 잘 보아야 한다.
compare의 리턴 값이 양수이면 두 숫자의 자리가 바뀌고, 음수 또는 0 이 나오면 자리가 바뀌지 않는다.
인자를 문자열 순서라 생각하자. 즉, o1 다음 o2가 있다고 생각하면 된다.
o1.length() - o2.length()
만약 이게 양수면, o1 > o2이다. 그래서 순서가 바뀌어 o2 o1 순서가 된다. 그래서 o1이 더 크기 때문에 오름차순이다.
이게 음수면 o1 < o2이다. 음수면 순서가 바뀌지 않아 그대로 o1 o2다. 그래서 o2가 더 크기 때문에 똑같이 오름차순이다.
결괏값 : a abc abcd
o2.length() - o1.length()
만약 이게 양수면, o2 > o1이다. 그래서 순서가 바뀌어 o2 o1 순서가 된다. 여기서 o2가 더 크기 때문에 내림차순이다.
이게 음수면 o1 > o2이다. 음수면 순서가 바뀌지 않아 그대로 o1 o2다. 그래서 o1이 더 크기 때문에 내림차순이 된다.
결괏값 : abcd abc a
Comparable<T> 인터페이스
comparable<T>는 java.lang 패키지에 포함되어 있는 인터페이스이다. 모든 Wrapper 클래스는 Comparable<T> 인터페이스를 구현하고 있다. comparable은 기본적으로 적용되는 정렬 기준이 되는 메소드를 정의해놨다고 한다. comparable의 메소드는 compareTo(<T> o1)이다.
x.compareTo(y)
- x가 y보다 작으면 음의 정수
- x가 y보다 크면 양의 정수
- 같으며 0 리턴
comparable VS comparator
이 둘의 차이를 볼 때, 기본적으로 적용되는 정렬 기준, 기본 정렬과는 다르게 정렬하고 싶을 때 사용한다라고 정의되어 있는데 처음에 볼 때는 언제 무엇을 써야할지 감이 안 온다. 나 역시 그랬다. 그래서 이 문제를 볼 땐 이걸 써야 한다라고 생각하지 않고 여기서는 비교해야 할 대상이 이렇게 구성되어 있으니 이 인터페이스가 더 편하겠다고 생각해야 한다. 이 두 문제를 비교하면서 보면 좋을 것 같다.
1181 단어 정렬
단어 정렬 문제에서는 list안에 있는 단어들끼리 size로 정렬한 뒤, 사전순으로 또 정렬한다. 그렇다면 이건 두 문자열을 비교해야 하므로 인자를 두 개 받는 comparator가 더 편하다고 생각이 들었다. 그래서 o1과 o2를 비교하여 문제를 해결했다.
11650 좌표 정렬하기
좌표 정렬하기 문제에서는 Point 클래스를 받아 x좌표, y좌표를 받았다. 여기서는 x좌표를 오름차순으로 정렬한 뒤, x좌표가 같으면 y좌표를 오름차순으로 정렬한다. 그래서 여기에서는 x를 먼저 비교한 뒤, y를 먼저 비교하게 된다. 물론 comparator도 사용할 수 있지만, x와 y를 따로 생각하여 문제를 더 수월하게 풀 수 있을 것 같아 comparable을 사용했다.
'Java' 카테고리의 다른 글
Object 메소드 (0) | 2021.05.24 |
---|---|
(TYPE) type -> String , String -> type(TYPE) (0) | 2021.05.24 |
컬렉션 프레임워크 : Queue, Deque (0) | 2021.04.04 |
컬렉션 프레임워크 : List < ArrayList, Vector, LinkedList, Stack > (0) | 2021.03.31 |
Scanner 사용 nextInt() / nextLine() / next() (0) | 2021.03.30 |