cleanUrl: /posts/what-you-consider-implements-comparable
share: true
Leecode 문제를 풀다가 Comparable
에 대한 정리가 필요한 순간이 왔다. Arrays.sort
를 사용하는데 어떻게 정렬하는지 조금 아리까리해서 이번 기회에 완전히 잡아야겠다는 생각이 들어 정리하게 되었다. 여기에 정리한 내용은 "Effective Java 14. Comparable을 구현할지 고민하라" 에서 필요한 부분만 발췌했다.
compareTo
는 Comparable 인터페이스에 유일하게 존재하는 method 이다.
interface Comaparable {
int compareTo(T t);
}
String
, Integer
와 같이 값을 갖는 모든 객체와 Enum
타입은 Comparable
을 구현했다.
Integer 클래스에서 구현한 Comparable
compareTo
는 주어진 객체의 순서를 비교한다.
객체가 주어진 객체보다 작으면 음의 정수, 같으면 0, 크면 양의 정수를 반환한다. 따라서 다음의 test 가 통과한다 만약 비교할 수 없는 타입이 주어지면 ClassCastException
이 발생한다.
@Test
@DisplayName(value =
"compareTo 가 음수가 나오게 하자")
void compareToMinus() {
Integer a = 1_000;
Integer b = 2_000;
assertThat(
// 대상객체 a는 1000이고
a.compareTo(b)
// 주어진 객체 b는 2000이다.
// 주어진 객체보다 작아 -1을 반환한다
).isNegative();
assertThat(
a.compareTo(b)
).isEqualTo(-1);
}
@Test
@DisplayName(value =
"compareTo 가 양수가 나오게 하자")
void compareToPlus() {
Integer a = 2_000;
Integer b = 500;
assertThat(
// 대상객체는 2,000 이고
a.compareTo(b)
// 주어진 객체는 500 이다.
// 주어진 객체보다 크기 때문에 1을 반환한다
).isPositive();
assertThat(
a.compareTo(b)
).isEqualTo(1);
}
eqauls
와 다음과 같은 내용이 매우 유사하다
(다음의 sgn
은 표현식이며 부호 함수를 의미한다 표현식이 음수, 0, 양수일때 -1, 0, 1을 반환한다)
sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
가 성립한다.
sgn(x.compareTo(y))
이 exception을 발생한다면 sgn(y.compareTo(x))
도 예외를 발생한다.x.compareTo(y) > 0 && y.compareTo(z) > 0
가 성립하면x.compareTo(z) > 0
도 성립한다x
, y
, z
에 대해
x.compareTo(y) == 0
이면sgn(x.compareTo(z)) == sgn(y.compareTo(z))
이 성립한다(x.compareTo(y) == 0) == (x.equals(y))
여야 한다.compareTo
는 동치인지 비교하는게 아니라 그 순서를 비교한다.만약 객체 참조의 필드를 비교하고자 한다면 재귀적으로 compareTo
를 호출해야 한다. 만약 Comparable
을 구현하지 않았다면 Compator
를 사용한다.
class PhoneNumber {
public int compareTo(PhoneNumber pn) {
int result = Short.comparable(areaCode, pn.areaCode); // 가장 먼저 비교할 필드
if (result == 0) {
result = Short.compare(prefix, pn.prefix); // 두번째로 비교할 필드
if (result == 0) {
result = Short.compare(lineNum, pn.lineNum); // 세번째로 비교할 필드
}
}
return result;
}
}
이 코드가 Java8 에 와서 굉장히 간지나게 변했다.