Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- AOP
- docker
- SQL
- DDL
- Test
- hashcode
- 필드 주입
- KEVISS
- VUE
- MSA
- 열 속성
- 바이너리 카운팅
- cache
- jwt
- stream
- DI
- StringBuilder
- select_type
- 생성자 주입
- lambda
- jpa
- 인덱스
- 테스트 코드
- Spring
- redis
- java
- 재정의
- equals
- 조합
- static
Archives
- Today
- Total
백엔드 개발자 블로그
[Effective Java] Item14. Comparable을 구현할지 고려하라 본문
Comparable 인터페이스의 compareTo 메서드를 구현하게 되면 동치성 비교와 순서 비교가 가능해집니다.
compareTo 메서드의 일반 규약
동치성
A == A 의 결과는 항상 true 이어야 합니다.
대칭성
A == B와 B == A 결과가 같아야 합니다.
추이성
A > B 이고 B > C 이면 A > C 이어야 합니다.
equals vs compareTo
내부적으로 정렬하는 곳(TreeSet, TreeMap, Collections, Arrays)에는 compareTo를 사용하고, 아닌 곳에는 equals를 사용하여 동치성 비교를 합니다. 아래 예시를 봅시다.
public static void main(String[] args) {
// 스케일이 다른 숫자를 넣는다.
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("1.00");
HashSet<BigDecimal> hset = new HashSet<>();
TreeSet<BigDecimal> tset = new TreeSet<>();
hset.add(bd1);
hset.add(bd2);
System.out.println("hset cnt is " + hset.size());
tset.add(bd1);
tset.add(bd2);
System.out.println("tset cnt is " + tset.size());
}
위 코드의 결과는 아래와 같습니다.
hset cnt is 2
tset cnt is 1
HashSet 클래스의 경우 내부적으로 순서를 고려하기 않기 때문에 동치성 비교시 equals를 사용합니다. 즉 소수점 정보까지 모두 고려해서 같은지 비교합니다. 따라서 hashSet 은 BigDecimal이 다르다고 판단하여 2개가 나왔습니다.
TreeSet 클래스의 경우 내부적으로 정렬을 하기 때문에 동치성 비교시 compareTo를 사용합니다. 스케일 정보를 포함하지 않으므로 두 BigDecimal을 같다고 판단하여 1개가 나왔습니다.
compareTo 구현 방법
Java 7 이전 : 정수 타입은 관계연산자(>,<)로, 실수 타입은 Double.compare와 Float.compare를 사용
Java 8 부터 : 박싱된 기본 클래스의 compare 정적 메소더 사용
// Comparator의 비교자 생성 메서드를 통해서 compareTo 메서드에 정렬 기준을 부여해줄 수 있다.
private static final Comparator<PhoneNumber> COMPARATOR =
comparingInt((PhoneNumber pn) -> pn.areaCode)
.thenComparingInt(pn -> pn.getPrefix())
.thenComparingInt(pn -> pn.lineNum);
@Override
public int compareTo(PhoneNumber pn) {
return COMPARATOR.compare(this, pn);
}
}
주의할 점
두값의 차이를 반환하는 메서드는 만들면 안됩니다. 정수 오버플로나 부도소수점 계산 방식에 따른 오류를 낼 수 있습니다.
static Comparator<Object> hashCodeOrder = new Comparator<>(){
public int compare(Object o1, Object o2) {
return o1.hashcode() - o2.hashcode();
}
}
'Java' 카테고리의 다른 글
String, StringBuffer, StringBuilder (0) | 2024.04.16 |
---|---|
[Effective Java] Item15. 클래스와 멤버의 접근 권한을 최소화하라 (0) | 2024.04.08 |
[Effective Java] Item13. clone 재정의는 주의해서 진행하라 (0) | 2024.04.05 |
[Effective Java] Item12. toString을 항상 재정의하라 (0) | 2024.04.04 |
[Effective Java] Item11. equals를 재정의하려거든 hashCode도 재정의하라 (0) | 2024.04.02 |