Comparator와 Comparable

정순동·2023년 12월 21일
0

자바기초

목록 보기
62/89

Comparator와 Comparable은 인터페이스로 컬렉션을 정렬하는데 필요한 메서드를 정의하고 있다.

Comparable을 구현하고 있는 클래스들은 같은 타입의 인스턴스끼리 서로 비교할 수 있는 클래스들, 주로 Integer와 같은 wrapper클래스와 STring, Date, File과 같은 것들이며 기본적으로 오름차순, 즉 작은 값에서부터 큰 값의 순으로 정렬되도록 구현돼 있다. 그래서 Comparable을 구현한 클래스는 정렬이 가능하다는 것을 의미한다.

Comparator / Comparable ↓

	public interface Comparator {
    	int compare(Object o1, Object o2);	// o1과 o2를 비교
        boolean equals(Object obj);
    }

	public interface Comparable {
    	int compareTo(Object o);	// 객체 자신(this)과 o를 비교
    }

compare()와 compareTo()는 선언 형태와 이름이 약간 다를 뿐 두 객체를 비교한다는 같은 기능을 목적으로 한다. compareTo()의 반환값은 int지만 실제로는 비교하는 두객체가 같으면 0, 비교하는 값보다 작으면 음수, 크면 양수를 반환하도록 설계해야 한다. compare()도 같다.

Comparable - 기본 정렬기준을 구현하는데 사용
Comparator - 기본 정렬기준 외에 다른 기준으로 정렬하고자 할 때 사용

equals메서드는 모든 클래스가 가지고 있는 공통적인 메서드(Object에서 내려옴)이지만, Comparator를 구현하는 클래스는 오버라이딩이 필요할 수 도 있다는 것을 알리기 위해 정의한 것일 뿐, 그냥 compare(Object o1, Object o2)만 구현하면 된다.

예제

public class ComparatorComparableExample {
    public static void main(String[] args) {
        String[] strArr = {"cat", "Dog", "lion", "tiger"};

        Arrays.sort(strArr);    // String의 Comparable구현에 의한 정렬
        System.out.println("strArr=" + Arrays.toString(strArr));

        Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); // 대소문자 구분안함
        System.out.println("strArr=" + Arrays.toString(strArr));

        Arrays.sort(strArr, new Descending()); // 역순 정렬
        System.out.println("strArr=" + Arrays.toString(strArr));
    }
}

class Descending implements Comparator {
    public int compare(Object o1, Object o2) {
        if(o1 instanceof Comparable && o2 instanceof Comparable) {
            Comparable c1 = (Comparable)o1;
            Comparable c2 = (Comparable)o2;
            return c1.compareTo(c2) * -1;   // -1을 곱해서 기본 정렬방식의 역으로 변경한다.
            // 또는 c2.compareTo(c1)와 같이 순서를 바꿔도 된다.
        }
        return -1;
    }
}

Arrays.sort()는 정렬할 때, Comparator를 지정하지 않으면 저장하는 객체(Comparable을 구현한 클래스의 객체)에 구현된 내용에 따라 정렬된다.

	static void sort(Object[] a)	// 객체 배열에 저장된 객체가 구현한 Comparable에 의한 정렬
    static void sort(object[] a, Comparator c)	// 지정한 Comparator에 의한 정렬

String의 Comparable 구현은 문자열이 사전 순으로 정렬되도록 작성돼 있다. 문자의 유니코드의 순서가 작은 값에서부터 정렬되는 것이다.

	public static final Comparator CASE_INSENSITIVE_ORDER

위의 Comparator를 사용하면 대 소문자 없이 정렬 가능하다.

	Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER);

만약 이해가 안된다면
https://tcpschool.com/java/java_collectionFramework_comparable
https://www.youtube.com/watch?v=EW3Mub24wYg
위 두링크를 참고하자.

Comparable : 일반적인 정렬이 필요할때 사용 , compareTo 메소드 사용
Comparator : 특정한 정렬기준이 필요할때 , compare() 메소드 사용

이렇게 Comparator, Comparable 구현이 된 메서드에서는 음수, 0, 양수 이렇게 3가지의 결과를 반환할텐데,
Arrays.sort()메서드에서 해당 메서드를 계속해서 호출하여 정렬을 하는것이다.

0개의 댓글