본문 바로가기

공부/개념 정리

Java) Comparable과 Comparator의 차이에 대해

Comparable과 Comparator 모두 두 객체를 "비교"할 때 사용한다. "정렬"을 할 때 사용되는 클래스 이지만 실제 작동 하는방식은 "두 객체를 비교 할 수 있도록 하는것" 이다. 그렇다면 왜 비교연산자를 사용하지 않고 두 클래스를 이용하는 이유는 객체를 단순히 비교할 수없는 상황이 있기 때문이다.

 

예를 들어 학생 클래스에 "반"과 "점수" 필드가 있다고 생각해보자. 이때 학생클래스 2개의 객체를 비교할 때 "반"을 기준으로 비교할지, 혹은 "점수"를 기준으로 비교할지 사용자가 지정을 해줘야 하기 때문이다.

 

그렇다면 Comparable과 Comparator의 차이는 무엇일까?

두 클래스는 인터페이스라는 공통점을 가지고 있다. Comparable은 int compareTo(T o) 메소드를 구현해야 하고, Comparator는 int compare(T o1, T o2) 메소드를 구현해야 한다.

간단히 Comparable의 compareTo(T o)는 "자신 객체"와, 매개변수로받는 "T o객체"를 비교하는 것이고

Comporator의 compare(T o1,T o2)는 매개변수로 받는"T o1"과 "T o2"를 비교하는 것이다.

 

Comparable의 사용법에 대해 알아보자.

우선 Comparable 인터페이스는 interface Comparable<T> { ... } 이런식으로 되어있다.

클래스를 만들 때 Comparable 인터페이스를 implements해준다. 이때 <>부분에는 내가 비교할 객체 타입을 넣어준다.

그리고 int compreTo(T o)메소드를 오버라이딩 해주면 된다.

이때 (T o)는 같은객체 끼리비교를 해야하니 <>에 넣어준 객체 타입과 같은 타입을 넣어준다. 그리고 내가 비교하고 싶은 객체의 필드를 비교해주면 된다.

 

예를들어 위의 학생 클래스를 비교한다고 한다면

public int compareTo(Student o){

if(this.age - o.age > 0){

return 1;

} else if( this.age == o.age){

return 0;

} else if( this.age - o.age<0){

return-1;

}

과같이 작성한다. 이때 반환값은 양수, 0 혹은 음수값으로 나오는 게 중요하다. 오버플로우가 나지 않을 크기라면 값의 크기는 중요하지 않다.

 

위와 마찬가지로 Comparator 인터페이스도 interface Comparator<T> { ... }이렇게 되어있다.

Comparable 인터페이스를 구현했던 것과 비슷하게 클래스를 작성할 때 implements를 해주면 된다. 이때의 방식은 Comparable 인터페이스를 구현했던것과 비슷하다.

<>에 비교할 객체 타입을 넣어준다. 그 후 int Compare(T o1, T o2) 메서드를 오버라이딩 해주면 된다.

 

위와 같은 예시를 들어보자.

public int compare(Student o1, Student o2){

if(o1.age - o2.age > 0){

return 1;

} else if(o1.age == o2.age){

return 0;

} else if(o1.age - o2.age<0){

return-1;

}

과 같이 작성한다. 

 

이때 compare()메서드는 compareTo()와 달리 두개의객체를 비교한다. 메서드를 실행하는 자신 객체는 비교에 참여하지 않는다. 이때문에 compare()메서드를 사용하기 위해 객체를 새로 생성해야한다. 이는 메모리 낭비로 이어지기에 compare() 메서드를 사용할 때는 익명 객체를 사용한다.(여기는 아직 잘이해가 안된다...)

 

comparable 인터페이스와 comparator 인터페이스의 차이를 알아봤던 이유는 배열의 sort()메서드의 매개변수로서 들어가기 때문이었다. comparator 객체를 받는 변수부분이 어떻게 작동하는지를 공부하기 위해서 공부를 시작했다. 근데 막상 공부하다 보니 sort메서드에서 해당 객체들이 어떻게 작동하는지는 알아 보기전에 팀원들과 스터디가 시작되었다.

내일은 배열의 sort함수를 공부하며 오늘 배운 comparable 인터페이스와 comparator가 어떤방식으로 sort메서드의 매개변수로서 작동하는지 알아봐야겠다.