본문 바로가기
Work/Java

[Java] Comparable, Comparator 인터페이스

프리미티브 자료형이 아닌 객체를 정렬하기위한 방법으로  Comparable , Comparator 인터페이스들을 활용할 수 있다.

둘다 인터페이스기 때문에 클래스에 implements를 통해 명시하여 제공되는 메소드를 구현해야한다.

 

둘의 차이는 

 

ComparablecompareTo(T o) 메소드를 오버로딩 해야하고, (클래스내 객체와 파라미터로 받은 객체를 비교한다)

Comparatorcompare(T o1, To2) 메소드를 오버로딩해서 사용한다. (파라미터로 받은 두 객체를 비교한다)

 

Comparable 은 Lang 패키지에 존재하여 import없이 더 간단하게 사용한다. 

ComparatorUtil 패키지에 존재하며, 객체의 오름차순 외에 다른정렬 방식을 원할때 많이 사용한다.

 

 

 

비교 메소드는 int를 반환하는 함수이며, 왼쪽 객체가 큰 경우 양수, 같은경우 0, 오른쪽 객체가 큰 경우 음수로 정의해야한다.

 

보통은 if를 통해 1,0,-1 을 반환하도록 하기도하지만,

    public int compareTo(Car obj) {
        if (this.modelYear == obj.modelYear) {
            return 0;
        } else if(this.modelYear < obj.modelYear) {
            return -1;
        } else {
            return 1;
        }
    }

오버플로우가 발생하지 않는 경우라면, 상황별로 나누지 않고 둘의 차를 나누도록 구현해도 된다. 

    public int compareTo(Car obj) {
        return this.modelYear - obj.modelYear;        
    }

 

메소드를 오버로딩 하고 나서 사용되는 Collections.sort()시

구현 한대로 비교하여 정렬하게된다.

 

 

Comparable 예제

public class Circle implements Comparable<Circle> {
    double radius;
    public Circle(double radius) {
        this.radius = radius;
    }
    @Override
    public int compareTo(Circle c) {
        return this.radius - c.radius;
    }
}

 

Comparator 예제

import java.util.Comparator;

public class Circle implements Comparator<Circle,Circle> {
    double radius;
    public Circle(double radius) {
        this.radius = radius;
    }
    @Override
    public int compare(Circle c1, Circle c2) {
        return c1.radius - c2.radius;
    }
}

 

 

호출부 코드

Circle a = new Circle(5);
Circle b = new Circle(1);
Circle c = new Circle(3);
Circle[] circles = {a, b, c};
Arrays.sort(circles);