본문 바로가기

Algorithm/Algorithm for Beginner

4. Comparator를 이용한 Array와 List의 정렬

Java프로그램에서 Array나 List에 저장된 value를 정렬할 때 가장 많이 쓰는 방식은 Arrays class나 Collections class를 import하여 정렬하는 방식입니다. 빠른 정렬을 개발자가 직접 구현하여 사용하는 것도 가능하지만, Arrays나 Collections에서 구현된 sort 함수는 정렬방식 중 가장 시간 복잡도가 작은 방식으로 최적화되어 있기 때문에 시간을 더 줄일 수 있지 않을까 하는 생각으로 직접 구현할 필요는 없습니다. 하지만 일반적인 Arrays.sort()나 Collections.sort()를 이용하다보면 발생하는 문제가 있습니다. Array든 List든 값을 오름차순으로만 정렬한다는 것과 이차원 배열 등 다차원 배열의 정렬이 되지 않는다는 것입니다. Java에서는 Comparator interface를 이용하여 정렬기준을 Override할 수 있도록 되어 있기 때문에 implements하여 구현하면 쉽게 정렬이 가능합니다. value가 객체일 경우 Comparable interface를 implements 하는 방식도 사용할 수 있지만, 제가 자주 사용하는 방식인 Comparator를 이용하여 구현하도록 하겠습니다. Comparator를 잘 사용하기만 하면 숫자의 내림차순 정렬, 단어의 정렬도 손쉽게 할 수 있을 뿐만 아니라 객체를 value로 갖고있는 Array나 List의 정렬, 다차원 배열 정렬도 손쉽게 할 수 있습니다. 

 

사용방식은 비교적 간단합니다. 일단 Arrays.sort()나 Collections.sort()를 이용하여 기존의 정렬방식과 동일하게 정렬하는 code를 작성하고, 정렬하려는 Array와 List 옆에 , 후 new Comparator를 선언합니다. Comparator를 선언하게 되면 어떤 Generic type을 사용할지 정해주게 되어있고, 그 type에 해당하는 정렬을 새로 정의할 수 있습니다. 정렬을 정의하는 부분은 compare 함수 부분에 들어가게 됩니다. 이때 기준이 되는 부분을 함수의 parameter로 받게 되는데 '비교'하는 것이기 때문에 parameter는 항상 두 개씩 받게 되어있습니다. parameter 값을 서로 비교한 후 return 시키는 값을 조정하는 식으로 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
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
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
 
public class ComparatorTest {
    public static void main(String[] args) {
        int[][] array = new int[5][2];
 
        // data가 아래와 같이 이차원 배열로 주어졌다고 가정합니다
        // 만일 오름차순으로 정렬시 이차원 배열 정렬의 기준이 0번째 행렬이면
        // 0, 2, 3, 1, 4 순으로 정렬될 것이고
        // 1번째 행렬이라면
        // 3, 2, 0, 4, 1 순으로 정렬될 것입니다.
        array[0][0= 10;
        array[0][1= 200;
        array[1][0= 30;
        array[1][1= 300;
        array[2][0= 15;
        array[2][1= 150;
        array[3][0= 25;
        array[3][1= 100;
        array[4][0= 50;
        array[4][1= 250;
 
        // 1번째 행렬로 정렬하기 위해 Comparator를 이용합니다
        Arrays.sort(array, new Comparator<int[]>() {
            // Override된 compare 함수를 어떻게 정의하냐에 따라서 다양한 정렬이 가능해집니다
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[1- o2[1];
                // 내림자순 정렬을 하고 싶다면 o2와 o1의 위치를 바꿔줍니다
                // return o2[1] - o1[1];
            }
        });
        
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i][0+ " " + array[i][1]);
        }
        System.out.println();
        
        // Node라는 class를 저장한 list를 val기준으로 정렬하는 예제입니다
        ArrayList<Node> list = new ArrayList<Node>();
        list.add(new Node(110));
        list.add(new Node(55));
        list.add(new Node(27));
        list.add(new Node(43));
        list.add(new Node(31));
 
        // list는 array와 다르게 Collections 함수를 이용하여 정렬합니다
        // 이때도 마찬가지로 Comparator를 사용합니다
        // 이번에는 val기준 내림차순 정렬해보겠습니다
        Collections.sort(list, new Comparator<Node>() {
            @Override
            public int compare(Node o1, Node o2) {
                return o2.val - o1.val;
            }
        });
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i).idx + " " + list.get(i).val);
        }
    }
}
 
class Node {
    int idx;
    int val;
 
    public Node(int idx, int val) {
        this.idx = idx;
        this.val = val;
    }
}
 
cs