Comparable은 객체 정렬에 필요한 메소드를 정의한 인터페이스이다.

Comparable은 compareTo() 메소드를 구현해야 한다.

 

Object의 equals보다 부가적인 기능이 더 추가된 메소드라고 보면된다. (순서비교가 가능하며 제네릭하다.)

 

일단 규약은 다음과 같다.

이 객체와 인자로 주어진 객체를 비교한다. 이 객체의 값이 인자로 주어진 객체보다 작으면 음수를, 같으면 0을, 크면 양수를 반환한다. 
인자로 전달된 객체의 자료형이 이 객체와 비교 불가능한 자료형인 경우에는 ClassCast Exception 예외를 던진다.
다음설명에서 sgn(expression)는 수학에서의 signum 함수를 나타내는 것으로 -1, 0, 1 가운데 한 값을 반환한다. 
어떤 값이 반환될지는 expression의 값이 음수인지, 0인지, 양수인지에 따라서 결정된다.


1. compareTo를 구현할 때는 모든 x와 y에 대해 sgn(x.compareTo(y)) == -sgn(y.compareTo.(x))가 만족되도록 해야 한다. 
(따라서 x.compareTo(y)는 y.compareTo(x)가 예외를 던질때에 한해 예외를 던져야 한다.)



2. compareTo를 구현할 때는 추이성을 보장해야 한다.. 즉, x.compareTo(y) > 0 && y.compareTo(z) 이면, x.compareTo(z) > 0 이어야 한다.



3. 마지막으로 x.compareTo(y) == 0 이면 sgn(x.compareTo(z)) == sgn(y.compareTo(z))의 관계가 모든 z에 대해 성립하도록 해야 한다.



4. 강력히 추천하지만 절대적으로 요구되는 것이 아닌 조건 하나는 x.compareTo(y) == 0 == (x.equals(y))이다. 
일반적으로 Comparable 인터페이스를 구현하면서 이 권고를 만족하지 않는 클래스는 반드시 그 사실을 명시해야한다.

다음과 같이 명시하면 적당할 것이다.
"주의: 이 클래스의 객체들은 equals에 부합하지 않는 자연적 순서를 따른다."
  • hashCode 규약을 지키지 못하면 해시를 사용하는 클래스와 어울리지 못하듯 compareTo도 마찬가지다.
  • compareTo()는 규약을 어길시 비교를 활용하는 클래스인 TreeSet, TreeMap, Collections, Arrays등과 어울리지 못한다.

 

 

책에서는 주로 compareTo의 규약에 대한 자세한 설명이 주를 이루는데

나는 활용방법에 대해 먼저 서술하겠다.

 

 

먼저 간단하게 comparable을 상속받은 User 객체를 만들어주었다.

 

 

그리고 ArrayList에 4개의 User객체를 생성해서 넣어주었다.

 

 

case 1: 나이순으로 정렬

 

 

이렇게 compareTo를 재정의 하면 나이순으로 오름차순으로 만들 수 있다.

그럼 숫자는 연산으로 간단하게 만들었지만 텍스트는 어떨까?

이럴 땐 주로 comparator를 사용하지만 comparable을 이용해서 만들어 보겠다.

 

 

case 2 : 이름순으로 정렬

 

간단한 꼼수지만 아스키 코드 차이를 이용해서 정렬해 보았다.

 

+ Recent posts