[JAVA] Comparable과 Comparator를 이용한 객체 비교와 이해 및 차이점

2024. 8. 30. 11:10·JAVA

Comprable, Comparator


Comparble과 Comparator는 JAVA에서 다양한 곳에 활용 되고 있다.

대표적으로 Heap(Priority Queue)자료구조가 있다. 이름도 비슷해서 헷갈릴 만한 두 인터페이스의 차이를 알아보자!

 

Comparble과 Comparator는 모두 인터페이스이므로 인터페이스 내 선언된 메서드를 반드시 구현해야 한다.

 

우선 두 인터페이스의 기본적인 구조를 알아보자

 

1. Comparable 인터페이스는 int 타입을 반환하는 compareTo(T o) 메서드를 가지고 있다.

2. Comparator 인터페이스는 선언된 메서드가 많다

    우리가 객체 비교를 위해 구현해야 할 메서드는 compare(T o1, T o2) 이다.

 

즉, Comparable 인터페이스를 사용하기 위해선 compareTo를 구현해야하고...

Comparator 인터페이스를 사용하기 위해선 compare를 구현해야 한다.


이런 인터페이스를 구현하여 사용하는 가장 큰 이유는 ❓

"객체를 비교할 수 있도록 한다" 에 목적을 두고 있다.

 

자바의 primitive 타입의 경우 값을 부등호로 비교가 가능하지만, 객체를 값처럼 비교하기에는 기준이 모호하다.

 

public class Person {
    int age;
    int height;
    
    public person(int age, int height) {
    	this.age = age;
        this.height = height;
    }
}

 

예시로 위의 클래스에서 객체를 생성한다면 어떤 사람은 나이로 비교하고 싶을 것이고 또 어떤 사람은 키로 비교하고 싶어할 수 있다. 또, 키가 같으면 나이가 많은 순으로 비교할래! 라는 사람도 있을 것이다.

 

두 인터페이스가 어떻게 객체를 비교하는지 알아보자.


비슷하면서도 다른 두 비교메서드 compareTo(T o) 와 compare(T o1, T o2) 의 차이점은 무엇일까?

 

짧게 정리해서 알아보면

1. 인자를 하나로 받는 compareTo(T o)는 필드에 있는 자기 자신과 매개변수 객체를 비교하는 것이다.

2. 인자를 두개로 받는 compare(T o1, T o2)는 자기 자신이 아닌 두 매개변수의 객체를 비교하는 것이다.


Comparable 인터페이스의 구조와 사용법 🔎

Java에서 Comparable 인터페이스를 들어가보면 

과 같이 인터페이스명 뒤에<T> 타입을 정해주는 Generic을 사용하고 있다.

또 구현해야 할 메서드도 보인다.

 

어떻게 사용할까?

public class Person Implements Comparable<Person> {
    int age;
    int height;
    
    public Person(int age, int height) {
    	this.age = age;
        this.height = height;
    }
    
    @Override
    public int compareTo(Person o) {
    	if (this.height > o.height ) return 1;
        else if (this.height == o.height) return 0;
        else return -1;
    }
}

키를 기준으로 비교해 봤다.

어떤 기준으로 1(양수)과 0, -1(음수)을 반환할까?

 

> 자기 자신이 비교 대상보다 크다 - 양수 반환

> 자기 자신이 비교 대상과 같다 - 0 반환

> 자기 자신이 비교 대상보다 작다 - 음수 반환

@Override
    public int compareTo(Person o) {
        return this.height - o.height;
    }

위 코드와 같이 하나의 계산식으로 세 개의 연산을 한번에 도출할 수 있다!

 

⚠️ 반드시 주의해야 할 점

메서드를 구현하기 전에 자료형의 범위를 파악해 보아야 한다. 예로 int 형의 범위는 -2³¹ ~ 2³¹-1 이다.

 

return Integr.MIN_VALUE - 1;

 

를 반환하면 주어진 범위의 상한선을 초과했기 때문에 Overflow가 발생한다.

따라서 연산을 하게 되면 2,147,483,647(양수)이 출력되기 때문에 비교에 오류가 발생할 수 있다!

 

자료형의 범위를 파악하여 Overflow를 방지하도록 하자


Comparator 인터페이스의 구조와 사용법 🔎

Comparator의 메서드 comapre(T o1, T o2)는 자기 자신이 아닌 두 매개변수 객체를 비교한다.

public class Person {
    int age;
    int height;
    
    public Person (int age, int height) {
    	this.age = age;
        this.height = height;
    }
    
    pubilc static void main(String[] args) {
    
    	Person[] people = new Person[10];
        people[0] = new Person(13, 180);
        people[1] = new Person(14, 160);
        ,
        ,
        ,
    	Arrays.sort(people, new Comparator<Person>() {
            @Override
            public int compare(Person p1, Person p2) {
                return p1.age - p2.age;
            }
        });
    }
}

 

마찬가지로 자료형의 범위를 꼭 파악하여 Overflow를 방지하자!!


대소 비교 🔎

compareTo 메서드와 compare 메서드 모두 음수, 0, 양수를 반환한다.

 

오름차순 기준으로

음수라는 말은 선행원소 < 후행원소 이므로 위치 교환이 일어나지 않는다.

양수라는 말은 선행원소 > 후행원소 이므로 위치 교환이 일어난다.

 

 

내림차순으로 비교하고 싶다면 ?

return -(this.height - o.height); // compareTo

return -(o1.height - o2.height); // comapre

반환 값의 부호를 반대로 설정해주자!


결론 📌

Java는 객체지향언어이기 때문에 객체의 비교를 정의하는 건 매우 중요하다.

많이 헷갈려할 수 있는 두 비교 인터페이스의 차이를 명확히 알고 있어야 한다.

아직 나도 차이를 완벽하게 이해한건 아니여서 더 공부해 볼 생각이다!

 

둘의 차이를 명확히 알고 적재적소에 잘 사용한다면 어떤 프로젝트를 하더라도 좋은 코드를 작성할 수 있을 것 같다.!

 

'JAVA' 카테고리의 다른 글

[JAVA] 자바의 default method  (0) 2025.02.24
'JAVA' 카테고리의 다른 글
  • [JAVA] 자바의 default method
의중
의중
  • 의중
    개발어려워
    의중
  • 전체
    오늘
    어제
    • 전체글 (31) N
      • Algorithm (12)
      • SSAFY (1)
      • 자료구조 (4)
      • 운영체제 (2)
      • JAVA (2)
      • ML, DL (0)
      • BackEnd (4)
      • DevOps (1)
      • 네트워크 (3)
      • DB, SQL (2) N
  • hELLO· Designed By정상우.v4.10.3
의중
[JAVA] Comparable과 Comparator를 이용한 객체 비교와 이해 및 차이점
상단으로

티스토리툴바