Item11 - equals를 재정의하려거든 hashCode도 재정의하라(2)
2023. 11. 22. 23:25ㆍBook/이펙티브 자바
좋은 해시 함수라면 서로 다른 인스턴스에 다른 해시코드를 반환한다. 이상 적인 해시 함수는 서로 다른 인스턴스들을 32bit 정수 범위에 균일하게 분배해야 한다. 다음은 좋은 hashCode를 작성하는 간단한 요령이다.
public final class PhoneNumber {
private final short areaCode, prefix, lineNum;
public PhoneNumber(int areaCode, int prefix, int lineNum) {
this.areaCode = rangeCheck(areaCode, 999, "area code");
this.prefix = rangeCheck(prefix, 999, "prefix");
this.lineNum = rangeCheck(lineNum, 9999, "line num");
}
... 코드 생략
// 코드 11-2 전형적인 hashCode 메서드 (70쪽)
@Override public int hashCode() {
//기본 타입 필드라면 Type.hashCode(f)
int result = Short.hashCode(areaCode);
result = 31 * result + Short.hashCode(prefix);
result = 31 * result + Short.hashCode(lineNum);
return result;
}
}
파생 필드는 해시코드 계산에서 제외해도 된다. 도한 equals 비교에 사용되지 않는 필드는 '반드시' 제외해야 한다.(규약 두 번째)
클래스가 불변이고 해시코드를 계산하는 비용이 크다면, 매번 새로 계산하기 보다는 캐싱하는 방식을 고려해야 한다. 해시의 키로 사용되지 않는 경우라면 hashCode가 지연 초기화 전략을 사용할 수 있다.(스레드 세이프하게)
private int hashCode; // 자동으로 0으로 초기화된다.
@Override public int hashCode() {
int result = hashCode;
if (result == 0) {
result = Short.hashCode(areaCode);
result = 31 * result + Short.hashCode(prefix);
result = 31 * result + Short.hashCode(lineNum);
hashCode = result;
}
return result;
}
'Book > 이펙티브 자바' 카테고리의 다른 글
Item13 - clone 재정의는 주의해서 진행하라 (2) | 2023.11.24 |
---|---|
Item12 - toString을 항상 재정의하라 (1) | 2023.11.23 |
Item11 - equals를 재정의하려거든 hashCode도 재정의하라 (0) | 2023.11.22 |
Item10 - equals는 일반 규약을 지켜 재정의하라(4) (1) | 2023.11.22 |
Item10 - equals는 일반 규약을 지켜 재정의하라(3) (1) | 2023.11.21 |