2. 반사성 : if x.compareTo(y) == 0 then sng(x.compareTo(z)) == sng(y.compareTo(z))
3. 추이성 : if x.compareTo(y) > 0 && y.compareTo(z) then x.compareTo(z) > 0
4. 동치성 : (x.compareTo(y) == 0) == (x.equals(y))
필수는 아니지만 꼭 지키는 게 좋다.
이 권고를 지키지 않는 모든 클래스는 그 사실을 명시해야 한다.
ex> 주의 : 이 클래스의 순서는 equals 메서드와 일관되지 않다.
compareTo 메서드 작성
Comparable : 제너릭 인터페이스
compareTo 메서드의 인수 타입은 컴파일타임에 정해짐.
public class CaseInsensitiveString implements Comparable<CaseInsensitiveString> {
private String s;
public int compareTo(CaseInsensitiveString cis) {
return String.CASE_INSENSITIVE_ORDER.compare(s, cis.s);
}
}
자바7 이후 : 관계 연산자 <와 >는 쓰지 않는다.
박싱된 기본 타입 클래스의 정적 메서드 compare 이용
ex> Double.compare, Float.compare
기본 타입 필드가 여럿일 때의 비교자
public class PhoneNumber implements Comparable<PhoneNumber> {
private short areaCode;
private short prefix;
private short lineNum;
PhoneNumber(short areaCode, short prefix, short lineNum) {
this.areaCode = areaCode;
this.prefix = prefix;
this.lineNum = lineNum;
}
public int compareTo(PhoneNumber phoneNumber) {
int result = Short.compare(areaCode, phoneNumber.areaCode);
if (result == 0) {
result = Short.compare(prefix, phoneNumber.prefix);
if (result == 0) {
result = Short.compare(lineNum, phoneNumber.lineNum);
}
}
return result;
}
public static void main(String[] args) {
PhoneNumber phoneNumber1 = new PhoneNumber((short)31, (short)784, (short)4324);
PhoneNumber phoneNumber2 = new PhoneNumber((short)31, (short)784, (short)4324);
PhoneNumber phoneNumber3 = new PhoneNumber((short)31, (short)784, (short)1000);
System.out.println("PhoneNumber.main :" + phoneNumber1.compareTo(phoneNumber2));
System.out.println("PhoneNumber.main :" + phoneNumber1.compareTo(phoneNumber3));
}
}
결과
PhoneNumber.main :0
PhoneNumber.main :3324
Process finished with exit code 0
#### 비교자 생성 메서드를 활용한 비교자
~~~ java
import java.util.Comparator;
import static java.util.Comparator.comparingInt;
public class PhoneNumber2 implements Comparable<PhoneNumber2> {
private static final Comparator<PhoneNumber2> COMPARATOR = comparingInt((PhoneNumber2 pn2) -> pn2.areaCode).thenComparingInt(pn2 -> pn2.prefix).thenComparingInt(pn2 -> pn2.lineNum);
private short areaCode;
private short prefix;
private short lineNum;
PhoneNumber2(short areaCode, short prefix, short lineNum) {
this.areaCode = areaCode;
this.prefix = prefix;
this.lineNum = lineNum;
}
@Override
public int compareTo(PhoneNumber2 phoneNumber2) {
return COMPARATOR.compare(this, phoneNumber2);
}
public static void main(String[] args) {
PhoneNumber2 phoneNumber1 = new PhoneNumber2((short)31, (short)784, (short)4324);
PhoneNumber2 phoneNumber2 = new PhoneNumber2((short)31, (short)784, (short)4324);
PhoneNumber2 phoneNumber3 = new PhoneNumber2((short)31, (short)784, (short)1000);
System.out.println("PhoneNumber2.main :" + phoneNumber1.compareTo(phoneNumber2));
System.out.println("PhoneNumber2.main :" + phoneNumber1.compareTo(phoneNumber3));
}
}
결과
PhoneNumber.main :0
PhoneNumber.main :1
Process finished with exit code 0
compareTo
compareTo 메서드의 일반 규약
1. 대칭성 : sng(x.compareTo(y)) == -sgn(y.compareTo(x))
2. 반사성 : if x.compareTo(y) == 0 then sng(x.compareTo(z)) == sng(y.compareTo(z))
3. 추이성 : if x.compareTo(y) > 0 && y.compareTo(z) then x.compareTo(z) > 0
4. 동치성 : (x.compareTo(y) == 0) == (x.equals(y))
compareTo 메서드 작성
compareTo 메서드의 인수 타입은 컴파일타임에 정해짐.
기본 타입 필드가 여럿일 때의 비교자
Process finished with exit code 0
Comparator의 보조 생성 메서드 종류