Comparable, Comparator 자바 정렬

Comparable, Comparator 자바 정렬


JAVA에서 정렬을 처리하는 방법은 배열의 경우 Arrays.sort(arr), 리스트의 경우 Collections.sort(list)를 사용하는 것이 일반적이다. 그런데 이 sort메소드 에서 정렬대상이 되는 arr 또는 list가 Reference Type의 오브젝트인 경우 Comparable 인터페이스를 구현하고 있어야 한다.


Primative Type 정렬

우선, Primative Type의 배열, 리스트인 경우 별다른 처리 없이 정렬이 가능하다.

1
2
3
4
5
6
7
8
9
10
public void sortInt() {
    // Primitive type 정렬 
    int[] arrInt = new int[]{1,10432};
    Arrays.sort(arrInt);
    // Collections.sort(list); // 리스트라면 Collections 사용
 
    // 정렬결과 출력
    for(int i : arrInt)
        System.out.print(i+" ");
}
cs


Reference Type 정렬

Reference Type인 String의 경우도 별다른 조치 없이 자동 정렬이 가능하다.

1
2
3
4
5
6
7
8
9
10
public void sortString() {
    // Reference type 정렬 
    String[] arrString = new String[]{"z""c""b""a"};
    Arrays.sort(arrString);
    // Collections.sort(list); // 리스트라면 Collections 사용
 
    // 정렬결과 출력
    for(String s : arrString)
        System.out.print(s+" ");
}
cs


이는 String, Integer, Date등의 JAVA에서 기본 제공해주는 Object의 경우는 기본적으로 Comparable 인터페이스를 구현하고 있기 때문이다. 그래서 사용자가 만든 객체를 sort 메소드를 통해서 정렬하거나, 혹은 다양한 조건을 기반으로 정렬하는 경우는 반드시 Comparable 인터페이스를 구현하여야 직접 정렬 기준을 구현하여야 한다.


Comparable 구현

Student Vo를 생성하여 Comparable 인터페이스를 구현하였다. Comparable 인터페이스를 구현하는 경우
public int compareTo(T) 메소드를 구현하고 내부에서 비교처리 후 int형 리턴으로 비교 결과를 리턴한다.
  • 양수리턴 : this 오브젝트가 앞에 위치
  • 음수리턴 : this 오브젝트가 뒤에 위치
  • 0리턴 : 동일한 값으로 간주하고 입력 순서 유지
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
public class Student implements Comparable<Student> {
    
    private String name;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
 
    public String getName() {
        return name;
    }
    
    public int getAge() {
        return age;
    }
    
    /**
     * 양수가 리턴 되는 경우 현재 Object가 앞
     * 음수가 리턴 되는 경우 현재 Object가 뒤
     * 0이 리턴되는 경우 동일 값으로 간주하고 입력순서 유지
     */
    @Override
    public int compareTo(Student o) {
        int result = this.getName().compareTo(o.getName());
        if(result == 0) {
            result = this.getAge() - o.getAge();
        }
        return result;
    }
}
cs


아래와 같이 테스트를 수행하는 경우

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
    Student s1 = new Student("홍길동", 27); 
    Student s2 = new Student("이지수", 31); 
    Student s3 = new Student("이지수", 30);
    Student[] arr = new Student[]{s1, s2, s3};
    
    Arrays.sort(arr);
    
    for(Student s : arr) {
        System.out.println(s.getName() + " " + s.getAge());
    }
}
cs


이렇게 이름순으로 먼저 정렬되고, 이름이 같은 경우 나이순으로 정렬된 결과를 얻는다.


이지수 30

이지수 31

홍길동 27


Comparator 구현

Comparator는 보통 다음과 같은 상황에서 사용된다.
  1. JAVA에서 기본제공하는 Reference Type을 내가 원하는대로 정렬하고 싶을때 (예시 : String, Integer를 역순으로 정렬 혹은 특정추가 조건)
  2. 기존에 구현된 Comparable의 정렬과는 다른 결과를 얻고 싶을 때

즉 기존에 구현되어 있는 Comparable 인터페이스 구현 대신에 다른 조건에 의해서 정렬하고자 하는 경우 사용된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void main(String[] args) {
    Student s1 = new Student("홍길동", 27); 
    Student s2 = new Student("이지수", 31); 
    Student s3 = new Student("이지수", 30);
    Student[] arr = new Student[]{s1, s2, s3};
    
    Arrays.sort(arr, new Comparator<Student>() {
        @Override
        public int compare(Student o1, Student o2) {
            return o1.getAge() - o2.getAge();
        }
    });
    
    for(Student s : arr) {
        System.out.println(s.getName() + " " + s.getAge());
    }
}
cs


Arrays.sort() 혹은 Collections.sort()에 두번째 인자로 Comparator 구현체를 전달하여 주면 된다.


홍길동 27

이지수 30

이지수 31


이렇게 별도 Comparator를 구현하는 경우 Comparable의 compareTo는 무시되고 Comparator의 compare메소드의 처리 결과를 기준으로 정렬하게 된다.

이 글을 공유하기

댓글

Email by JB FACTORY