언어/Java

[Java] 정렬 Comparable vs Comparator 사용

쿠큭다스 2021. 7. 16. 19:06
728x90

기본 지식

Arrays.sort() -> 일반적인 배열의 정렬시 사용

Collection.sort() -> 리스트의 정렬시 사용

 

 

<출력 결과>

 

 

그렇다면 Comparable & Comparator는 언제쓰일까??

 

공통점

- 객체간의 비교시 사용

 

차이점

- Comparable 인터페이스 : 객체간의 기본 정렬기준이 필요할 때 사용

                                  : compareTo(Type o) 메서드 구현을 통해 사용

                                  : 매개변수가 하나인 이유? "자기 자신"과 하나의 매개변수를 비교

 

- Comparator 인터페이스 : 객체간의 특정한 정렬기준이 필요할 때 사용

                                  : compare(Type o1, Type o2) 메서드 구현을 통해 사용

                                  : 매개변수가 두개인 이유? 두개의 매개변수를 비교

 

예를들어, 위와 같은 number1, number2를 비교하는 상황을 가정해보자.

Test를 정렬하고자 하는 경우 => 2개의 매개변수 중 무엇을 기준으로 정렬할지 몰라 에러가 뜬다.

 

Comparable 사용

ex) number2를 오름차순으로 정렬하고 싶을 때

 

 위와 같이 Comparable 인터페이스를 implements한 후에 compareTo() 메서드를 통해 사용한다.

 자기자신과 매개변수로 오는 수의 차이를 비교한 뒤,

 결과가 0이나 음수이면 자리바꿈을 하지 않고, 양수가 나오면 두 수를 교환하는 작용이 일어나 위치가 변경된다.

 

 만약, this.number2=10, o.number2=20이 나온다면 10-20<음수이므로 교환이 일어나지 않고

 this.number2=20, o.number2=10이 나온다면 20-10>양수이므로 두 수의 교환이 일어난다.

 따라서 아래와 같이 오름차순으로 정렬이 가능하다.

 (내림차순일 경우에는 위와 반대로 return o.number2-this.number2로 설정하면 된다.)

 

 

Comparator의 사용

ex) number1은 오름차순, number1이 같은경우, number2는 내림차순으로 정렬

 

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
 
import java.util.Arrays;
import java.util.Comparator;
 
public class Test{
    
    private int number1;
    private int number2;
    
    public Test(int number1, int number2) {
        this.number1=number1;
        this.number2=number2;
    }
    
    public static void main(String[] args) {
        
        Test test[]=new Test[5];
        test[0]=new Test(1,20);
        test[1]=new Test(1,10);
        test[2]=new Test(4,40);
        test[3]=new Test(2,20);
        test[4]=new Test(5,50);
        
        Arrays.sort(test,new Comparator<Test>() {
            
            @Override
            public int compare(Test o1, Test o2) {
                if (o1.number1>o2.number1) {
                    return 1// number1에 대해서는 오름차순
                }
                else if (o1.number1==o2.number1) { // number1이 같은 경우
                    if(o1.number2<o2.number2) {
                        return 1// number2에 대해서는 내림차순
                    }
                }
                return -1;
            }
            
        });
        
        for(Test t:test) {
            System.out.println("number 1의 값:"+t.number1+", number 2의 값:"+t.number2);
        }
 
    }
 
}
 
 
 

 

Comparable과 마찬가지로, return 값의

결과가 0이나 음수이면 자리바꿈을 하지 않고, 양수가 나오면 두 수를 교환하는 작용이 일어나 위치가 변경된다.

 

return 값으로 compareTo 함수를 쓰는 경우

 

ex) return s1.compareTo(s2);와 같이 표기하는 경우

(s1=10, s2=20)

s1과 s2의 비교시

s1<s2 -> s1-s2<0 이므로 음수가 되어 교환하지 않고 그대로 정렬 -> 오름차순

 

ex) return (s2+s1).compareTo(s1+s2);와 같이 표기하는 경우

(s1="a", s2="c")

s2이후 s1을 합친 값과, s1이후 s2를 합친 값의 비교시

s2+s1>s1+s2, (s2+s1)-(s1+s2)>0이므로 양수가 되어 두 문자열을 교환 -> 내림차순

 

따라서 두 매개변수의 비교시

처음 매개변수를 먼저쓰는 경우 오름차순, 처음 매개변수를 나중에 쓰는 경우 내림차순으로 정리할 수 있다.

 

 

[두 수의 비교 결과에 따른 작동 방식]

 

음수일 경우 : 두 원소의 위치를 교환 안함 (기본적으로는 오름차순)

양수일 경우 : 두 원소의 위치를 교환 함

 

728x90