본문 바로가기

Java/Java

[Java] compareTo

compareTo는 Comparable에 있는 메소드로, 객체들의 비교를 하게 해주는 메소드이다. 

Comparable의 코드를 보자.

public interface Comparable<T> {
    // compareTo는 자신이 비교대상보다 크다면 1
    // 더 작다면 -1
    // 같다면 0을 리턴한다.
    public int compareTo(T o);
}

 

자바의 WrapperClass들은 기본적으로 compareTo를 구현하고있다.

예로, String이 구현하고있는 compareTo 메소드를 확인해보자.

    public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

String은 자신의 문자와 비교대상(anotherString)의 문자를 한글자씩 끊어서 비교를하며 더 큰 문자를 출력하는걸 볼수있다.

우리가 Arrays.sort()나, Collections.sort()메소드를 호출해 콜렉션을 정렬할때, 이들은 내부적으로 자신이 담고있는 객체의 compareTo()메소드를 호출해 객체를 정렬한다.

즉, .sort() 메소드를 이용해 정렬하고싶다면, 반드시 compareTo를 오버라이드해서 구현해야한다.

 

이제 우리가 만든 객체에 compareTo를 구현하고 이를 Collection객체(sort를 지원하는)에 넣은후 .sort메소드를 이용해 정렬해보자.

 

나는 C++에서 주로 사용하던 pair(int만 저장가능하다)를 자바에서 구현해보도록 하겠다.

package ForPost;

public class Pair {
    public int first, second; // 외부에서 .first, .second로 접근할수있게 public으로 선언한다. 
    
    public Pair(int first, int second){ // 생성자 first와 second의 값을 전달받는다.
        set(first, second); // set메소드를 호출해 first와 second값을 변경한다.
    }
    
    public void set(int first, int second){ 
        // 값을 변경하는 메소드이다.
        // 외부에서 set메소드를 호출해 변경할수있도록 public으로 선언했다.
        this.first = first;
        this.second = second;
    }
}

Pair클래스이다. 위 Pair클래스를 ArrayList에 넣고 정렬해보자.

package ForPost;

import java.util.*;

public class Main {
    
    public static void main(String[] args){
        ArrayList<Pair> arrayList = new ArrayList<Pair>();
        arrayList.add(new Pair(1,4));
        arrayList.add(new Pair(1,3));
        arrayList.add(new Pair(1,2));
        Collections.sort(arrayList);
    }
    
}

arrayList에 (1,4) (1,3) (1,2)를 넣었다. 정렬후 예상출력은 (1,2) (1,3) (1,4)이다.

위 코드는 컴파일 되지않는다.

그 이유는 Pair가 compareTo를 구현하지 않았기 때문이다. Pair에 compareTo구현을 넣어주자.

 

package ForPost;

public class Pair implements Comparable<Pair>{
    public int first, second; // 외부에서 .first, .second로 접근할수있게 public으로 선언한다. 
    
    public Pair(int first, int second){ // 생성자 first와 second의 값을 전달받는다.
        set(first, second); // set메소드를 호출해 first와 second값을 변경한다.
    }
    
    public void set(int first, int second){ 
        // 값을 변경하는 메소드이다.
        // 외부에서 set메소드를 호출해 변경할수있도록 public으로 선언했다.
        this.first = first;
        this.second = second;
    }
    
    @Override
    public int compareTo(Pair p){
        if(p.first < this.first) return 1; 
        if(p.first > this.first) return -1;
        if(p.first == this.first){
            if(p.second < this.second) return 1;
            if(p.second > this.second) return -1;
        }
        return 0; // 같다면 0
    }
    
}

Pair에 Comparable인터페이스를 구현했으니 다시 Main클래스로 돌아가 실행시켜보자,

잘 실행되는걸 확인할수있다.

 

이처럼 Collections나 Arrays에서 제공하는 sort메소드를 이용해 정렬하기위해선 compareTo를 반드시 구현해야한다.

 

 

'Java > Java' 카테고리의 다른 글

[Java] Future.cancel() vs CompletableFuture.cancel()  (0) 2023.02.15
[Java] 스레드와 Synchronized  (0) 2021.10.25
[Java] Java Heap Stack Static  (0) 2021.10.23
[Java] Wrapper Class  (0) 2021.05.02
[Java] ArrayList  (0) 2021.05.02