티스토리 뷰
1. Collections
- Collections는 내부에 static함수가 있기 때문에 객체를 생성하지 않고 바로 메소드를 사용 할 수 있다.
- Collection 프레임워크 등에서 sort()를 사용하면 컴퓨터가 알아서 정렬을 해 주는데 오늘은 sort()를 이용한 정렬에 대해 알아보고자 한다.
- 여기서 sort()는 Comparable 구현에 의해 정렬된 것이다.
2. Array.sort()와 Collections.sort()의 차이점은? 아래와 같이 쉽게만 이해하자!
가. Array.sort()
- 배열 정렬의 경우
나. Collections.sort()
- List Collection 정렬의 경우
3. Comparator과 Comparable은 무엇이 다른가?
- Comparator : 기본 정렬기준 외에 다른 기준으로 정렬하고자 할 때 사용
- Comparable : 기본 정렬기준을 구현하는데 사용
- 오늘은 Comparator 사용 예제를 다루고 Comparable은 무엇인지 알고만 넘어가고자 한다.
4. Comparator
- 정렬 가능한 클래스(Comparable 인터페이스를 구현한 클래스)등릐 기본 정렬기준과 다르게 정렬하고 싶을 때
- 주로 익명 클래스로 사용되고 기본적인 정렬 방법인 오름차순 정렬을 내림차순으로 정렬할 때 많이 사용한다.
- Collections 내부에 Comparator 가 존재하는데 인터페이스이기 때문에 구현해서 사용해야 한다.
- Comparator은 정렬 중에서 가장 빠르다는 퀵 정렬을 사용하고 있고 최적화 되어 있기 때문에 직접 정렬 함수를 구현하는 것 보다 훨씬 바르기 때문에 Comparator 인터페이스를 사용하는 것이 좋다.
가. 구현방법
- Comparator interface를 implements 후 compare() 메서드를 오버라이드한 myComarator class를 작성한다.
- compare() 메서드 작성법
- 첫 번째 파라미터로 넘어온 객체 < 두 번째 파라미터로 넘어온 객체 : 음수 리턴
- 첫 번째 파라미터로 넘어온 객체 == 두 번째 파라미터로 넘어온 객체 : 0 리턴
- 첫 번째 파라미터로 넘어온 객체 > 두 번째 파라미터로 넘어온 객체 : 양수 리턴
- 음수 또는 0이면 객체의 자리가 그대로 유지되며, 양수인 경우에는 두 객체의 자리가 변경된다.
나. 사용방법
- Arrays.sort(array, myComparator)
- Collections.sort(list, myComparator)
- Arrays.sort(), Collections.sort() 메서드는 두 번째 인자로 Comparator interface를 받을 수 있다.
5. Comparable
- 정렬 수행 시 기본적으로 적용되는 정렬 기준이 되는 메서드를 정의하는 인터페이스
- Java에서 제공되는 정렬이 가능한 클래스들은 모두 Comparable 인터페이스를 구현하고 있으며, 정렬 시에 이에 맞게 정렬이 수행된다.
가. 구현방법
- 정렬할 객체에 Comparable inteface를 implements 한 후, compareTo() 메서드를 오버라이드하여 구현한다.
- compateTo() 메서드 작성법
- 현재 객체 < 파라미터로 넘어온 객체 : 음수 리턴
- 현재 객체 == 파라미터로 넘어온 객체 : 0리턴
- 현재 객체 > 파라미터로 넘어온 객체 : 양수 리턴
- 음수 또는 0이면 객체의 자리가 그대로 유지되며, 양수인 경우에는 두 객체의 자리가 바뀐다.
나. 사용 방법
- Arrays.sort(array)
- Collections.sort(list)
6. 정렬 예제(LinkedList와 Collections, Comparator 활용)
가. LinkedList와 객체(인수 2개)를 이용한 정렬
- 아래에 있는 클래스를 이용해 5개의 예제 실시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class A {
// 필드
int n;
String s;
// 생성자
public A(int n, String s) {
this.n = n;
this.s = s;
}
// 메서드
void output() {
System.out.println("num : " + n + ", s : " + s);
}
}
|
cs |
- Main 함수
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// Main
public static void main(String[] args) {
LinkedList<A> list = new LinkedList<A>();
list.add(new A((int)(Math.random()*100) % 100, "호랑이"));
list.add(new A((int)(Math.random()*100) % 100, "코끼리"));
list.add(new A((int)(Math.random()*100) % 100, "독수리"));
list.add(new A((int)(Math.random()*100) % 100, "맘모스"));
list.add(new A((int)(Math.random()*100) % 100, "코뿔소"));
System.out.println("정렬 전");
for (A item : list) {
item.output();
}
System.out.println("----------------------------------");
}
|
cs |
- Ex01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// Ex01
// 가장 기본적인
Collections.sort(list, new Comparator<A>() {
// compare 함수를 사용하여 정렬을 어떻게 할 것인지 정의한다.
@Override
public int compare(A o1, A o2) {
// 순차 정렬을 해주는 코드(역방향은 부등호를 변경하거나 return 값을 바꿔주면 됨)
// if-else 동등의 개념을 포함 , -1이 있기 때문에 +1로 적어서 동등하게 맞춰준다.
if(o1.n > o2.n) // if(o1.n < o2.n) : 역순
return +1; // 양수의 대명사를 +1이라고 본다.
else
return -1;
}
});
|
cs |
- Ex02
1
2
3
4
5
6
7
8
9
10
|
// Ex02
// Ex01의 compare 함수 안 코드를 삼항 연산자로 변경
Collections.sort(list, new Comparator<A>() {
// compare 함수를 사용하여 정렬을 어떻게 할 것인지 정의한다.
@Override
public int compare(A o1, A o2) {
return (o1.n > o2.n) ? +1 : -1;
}
});
|
cs |
- Ex03
1
2
3
4
5
6
7
8
9
|
// Ex03
// o1.n은 양수를, o2.n은 음수를 반환받는 것이기 때문에 Ex01 처럼 if-else를 사용하지 않아도 된다.
Collections.sort(list, new Comparator<A>() {
@Override
public int compare(A o1, A o2) {
return o1.n - o2.n;
}
});
|
cs |
- Ex04
1
2
3
4
5
6
7
8
|
// Ex04
// Ex03을 람다식으로 변환
// new를 없애고 함수 이름을 없앤 다고 생각하고 없애면 된다. 인수의 타입은 선언하지 않아도 된다
// 람다식으로 변환하는 방법만 알아두면 앞으로도 쉽게 람다식으로 변환 할 수 있다.
Collections.sort(list, (o1, o2) -> {
return o1.n - o2.n;
});
|
cs |
- Ex05
1
2
3
4
5
|
// Ex05
// Ex04를 다른형태의 람다식으로 변환
// 람다식 안에 코드가 한 줄 일 경우 스코프를 생략 할 수 있는데 return도 같이 제거해 주어야 한다.
Collections.sort(list, (o1, o2) -> o1.n - o2.n );
|
cs |
- 위 Ex01 - Ex05 까지 모두 같은 실행결과를 가지는 예제이다.
- 동일한 결과 값을 출력하는 5가지의 예시지만 Ex01 기본적인 사용법부터 Ex05 까지 코드를 줄이면서 변형한 예제 까지 알아두면 좋다. (람다식 적용)
- 만약에 A클래스의 필드 n이 float형이라면 반드시 Ex02 예제 처럼 코드를 작성해야 하며 int인 경우에는 모든 예제를 사용 해서 코드를 작성 할 수 있지만 Ex05 번이 가장 많이 사용 되는 예제이다.
나. LinkedList와 객체(인수 3개)를 이용한 정렬
- '가'에서 나온 예제와 유사하지만 클래스에 필드 변수를 하나 더 선언해 인수 3개를 활용한 예시이다.
- '나'는 필드 n1과 n2의 곱을 가지고 정렬하는 예제로 '가' 예제와 큰 차이가 없다.
- 전체 소스코드
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
|
package D_0723;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
// LinkedList 정렬 기법2
// n1과 n2를 곱한 값의 정렬
class A1 {
// 필드
int n1, n2;
String s;
// 생성자
public A1(int n1, int n2, String s) {
this.n1 = n1;
this.n2 = n2;
this.s = s;
}
// 메서드
void output() {
System.out.println("n1 : " + n1 + ", n2 : " + n2 + ", s : " + s);
}
}
public class Ex02 {
public static void main(String[] args) {
LinkedList<A1> listA = new LinkedList<A1>();
listA.add(new A1(12, 13, "호랑이"));
listA.add(new A1(10, 11, "코끼리"));
listA.add(new A1(15, 14, "독수리"));
listA.add(new A1(8, 10, "맘모스"));
listA.add(new A1(5, 11, "코뿔소"));
System.out.println("정렬 전");
for (A1
item : listA) {
item.output();
}
System.out.println("----------------------------------");
// n1과 n2를 곱한 값의 정렬
Collections.sort(listA, new Comparator<A1>() {
@Override
public int compare(A1 o1, A1 o2) {
int r1 = o1.n1 * o1.n2;
int r2 = o2.n1 * o2.n2;
if(r1 > r2)
return +1;
else
return -1;
}
});
System.out.println("정렬 후");
for (A1
item : listA) {
item.output();
}
}
}
|
cs |
- 실행결과
'Java' 카테고리의 다른 글
[JAVA] instanceof 연산자 (0) | 2019.07.23 |
---|---|
[JAVA] LinkedList의 C.R.U.D (0) | 2019.07.23 |
[JAVA] 자료구조 클래스 - LinkedList(연결리스트) (0) | 2019.07.22 |
[JAVA] Collection(List, Set, Map)의 종류와 이해 (0) | 2019.07.21 |
[JAVA] Network(Client, Server) (0) | 2019.07.21 |
댓글