4. Comparable 구현의 장점?
• Comparable 인터페이스를 구현한 객체들의 배열
– Arrays.sort(Type)
• Comparable 인터페이스를 구현한 객체들의 Collection
– Collections.sort(List)
Comparable 인터페이스에 의존하는 알고리즘 및 컬렉션
클래스들을 이용가능!
실제 자바 라이브러리의 모든 값 클래스들은 Comparable 인터페
이스를 구현 함
5. Comparable의 보편적인 계약
1. 모든 x와 y에 대하여
sgn(x.compareTo(y))=-sgn(y.compareTo(x))
가 되도록 해야 한다.
2. x.compareTo(y)>0 && y.compareTo(z)>0 이면
x.compareTo(z)>0 이어야 한다.
3. x.compareTo(y)==0 이라면, 모든 z에 대해
sgn(x.compareTo(z))==sgn(y.compareTo(z)) 이 되어야 한
다.
4. (x.compareTo(y) == 0) == (x.equals(y)) 가 되도록 하는 것이
좋다.
6. • compareTo 메소드에서 동일 여부를 검사할 때 equals 계
약 조항과 같은 제약을 따라야 한다.
– Reflexivity
– Symmetry
– Transivity
Comparable의 보편적인 계약
7. • compareTo 메소드에서의 비교가 equals메소드와 일치 X
정렬 컬렉션들은(TreeSet, TreeMap, …) 컬렉션 인터페이스의 보
편적 계약을 따르지 않을 수 있다.
BigDecimal 클래스의 compareTo 메소드와 equals 메소드가 일치
하지 않는다고 하면, new BigDecimal(“1.0”)와 new
BigDecimal(“1.00”) 두 객체를 HashSet에 추가한다면 두 객체 모
두 저장 되지만, TreeSet에 저장한다면 하나만 저장될 것.
Comparable의 보편적인 계약
8. Comparable의 구현
• 비교할 필드가 여러 개인 클래스
의 경우에는 순서대로 비교
– 필드 값이 같지 않으면 바로
return
– 모두 같으면 0 return
public int compareTo(PhoneNumber pn) {
// 지역 코드를 비교한다
if (areaCode < pn.areaCode)
return -1;
if (areaCode > pn.areaCode)
return 1;
// 지역 코드가 같으므로, 국번호를 비교한다
if (prefix < pn.prefix)
return -1;
if (prefix > pn.prefix)
return 1;
// 지역 코드와 국번호가 같으므로, 회선 번호
를 비교한다
if (lineNumber < pn.lineNumber)
return -1;
if (lineNumber > pn.lineNumber)
return 1;
// 모든 필드의 값이 동일하다
return 0;
}
9. Comparable의 구현
• 비교할 필드가 여러 개인 클래스
의 경우에는 순서대로 비교
– 필드 값이 같지 않으면 바로
return
– 모두 같으면 0 return
public int compareTo(CopyOfPhoneNumber pn) {
// 지역 코드를 비교한다
int areaCodeDiff = areaCode - pn.areaCode;
if (areaCodeDiff != 0)
return areaCodeDiff;
// 지역 코드가 같으므로, 국번호를 비교한다
int prefixDiff = prefix = pn.prefix;
if (prefixDiff != 0)
return prefixDiff;
// 지역 코드와 국번호가 같으므로, 회선 번호
를 비교한다
return lineNumber - pn.lineNumber;
}
10. Comparable의 구현
• 비교할 필드가 여러 개인 클래스
의 경우에는 순서대로 비교
– 필드 값이 같지 않으면 바로
return
– 모두 같으면 0 return
오버플로우 발생 가능!
public int compareTo(CopyOfPhoneNumber pn) {
// 지역 코드를 비교한다
int areaCodeDiff = areaCode - pn.areaCode;
if (areaCodeDiff != 0)
return areaCodeDiff;
// 지역 코드가 같으므로, 국번호를 비교한다
int prefixDiff = prefix = pn.prefix;
if (prefixDiff != 0)
return prefixDiff;
// 지역 코드와 국번호가 같으므로, 회선 번호
를 비교한다
return lineNumber - pn.lineNumber;
}