*compareTo
메서드란 ?*Comparable
인터페이스의 일부로 제공되며, 객체들을 서로 비교할 수 있게 해주는 기능을 제공equals
메서드와 비교하여 compareTo
는 단순 동치성 비교에 더해 순서까지 비교할 수 있으며, 제네릭함.Object
클래스의 메서드가 아님순서 비교 기능
compareTo
메서드는 객체들의 순서를 비교할 수 있어, 객체를 정렬하거나 최대/최소 값을 찾는 데 사용될 수 있음Arrays.sort()
메서드가 내부적으로 객체의 compareTo
를 사용제네릭 지원
Comparable
인터페이스는 제네릭을 지원하여, 동일한 타입의 객체들만 비교하도록 강제함.
public interface Comparable<T> {
int compareTo(T t);
}
자바 플랫폼과의 통합
String
, BigDecimal
)과 모든 열거 타입은 Comparable
인터페이스를 구현하여 자연스러운 순서를 가집니다.PhoneNumber
클래스에 Comparable
인터페이스를 구현
전화번호를 지역 코드, 프리픽스, 줄 번호 순으로 비교
public class PhoneNumber implements Comparable<PhoneNumber> {
private int areaCode;
private int prefix;
private int lineNumber;
public PhoneNumber(int areaCode, int prefix, int lineNumber) {
this.areaCode = areaCode;
this.prefix = prefix;
this.lineNumber = lineNumber;
}
@Override
public int compareTo(PhoneNumber other) {
int result = Integer.compare(this.areaCode, other.areaCode);
if (result == 0) {
result = Integer.compare(this.prefix, other.prefix);
if (result == 0) {
result = Integer.compare(this.lineNumber, other.lineNumber);
}
}
return result;
}
@Override
public String toString() {
return String.format("%d-%d-%d", areaCode, prefix, lineNumber);
}
}
사용 예
TreeSet
에 추가하면 자동으로 전화번호 순으로 정렬됨public static void main(String[] args) {
Set<PhoneNumber> phoneNumbers = new TreeSet<>();
phoneNumbers.add(new PhoneNumber(408, 555, 1234));
phoneNumbers.add(new PhoneNumber(408, 555, 4321));
phoneNumbers.add(new PhoneNumber(209, 555, 1234));
for (PhoneNumber pn : phoneNumbers) {
System.out.println(pn);
}
}
출력 결과
209-555-1234
408-555-1234
408-555-4321
equals의 규약과 비슷하지만 다른 점 존재!
hashCode 규약을 지키지 못하면 해시를 사용하는 클래스와 어울리지 못하듯, compareTo 규약을 지키지 못하면 비교를 활용하는 클래스와 어울리지 못함
아래 세 규약은 compareTo 메서드로 수행하는 동치성 검사도 equals 규약과 똑같이 반사성, 대칭성, 추이성을 충족해야 함을 뜻함 (equals와 주의사항, 우회법도 똑같음)
Comparable을 구현한 클래스는 모든 x, y에 대해 sgn(x.compareTo(y)) == -sgn(y.compareTo(x))여야 한다(따라서 x.compareTo(y)는 y.compareTo(x)가 예외를 던질때에 한해 예외를 던져야 함
= 두 객체 참조의 순서를 바꿔 비교해도 예상한 결과가 나와야 함
Comparable을 구현한 클래스는 추이성을 보장해야 한다. 즉, (x.compareTo(y) > 0 && y.compareTo(z) > 0)이면 x.compareTo(z) > 0이다.
Comparable을 구현한 클래스는 모든 z에 대해 x.compareTo(y) == 0이면 sgn(x.compareTo(z)) == sgn(y.compareTo(z))다.
= 크기가 같은 객체들끼리는 어떤 객체와 비교하더라도 항상 같아야 함
필수는 아니지만 꼭 지키길 권하는 규약
⇒ compareTo 메서드로 수행한 동치성 테스트의 결과가 equals와 같아야 한다는 것