앞의 아이템에서 살펴본 equals를 재정의할 때에는, hashCode도 반드시 같이 만들어줘야 한다. 심지어 Lombock에서는 @EqualsAndHashCode
로 어노테이션이 합쳐져있어, 항상 함께 만들어줘야 하기도 한다. (잘 쓰이지는 않지만 Google의 AutoValue라는 라이브러리 안에서도 함께 만들어지게 되어있다.)
해시테이블의 성능 고려?
제대로 사용하지 않으면 LinkedList의 원리와 다를 바 없게 동작하기 때문에, Hash를 제대로 효율적으로 쓰기 위해서는 HashCode를 올바르게 쓰는 방법을 알아야 하는 것임
@Override public int hashCode() {
int result = Short.hashCode(areaCode);
result = 31 * result + Short.hashCode(prefix);
result = 31 * result + Short.hashCode(lineNum);
return result;
}
핵심 필드 하나의 값의 해쉬값을 계산해서 result값을 초기화한다.
해당 객체의 나머지 핵심 필드 각각에 대해 다음 작업을 수행한다.
result = 31 * result + 해당 필드의 hashCode 계산값
31을 쓰는 이유?
31이라는 소수를 썼을 때, hash collision이 가장 적게 났다고 한다. 그래서 이제는 관습처럼 쓴다고.
result를 리턴한다.
Objects 클래스의 hash 메소드 사용
: 보통 우리가 인텔리제이에서 사용하는 방법
@Override
public int hashCode() {
return Objects.hash(areaCode, prefix, lineNum);
}
안에 타고 들어가보면 위에서 구현한 것과 유사하게 구현되어있다.
Object.hash()
를 사용하면 된다.
Lombock으로 사용하면 -> 내가 테스트 할 필요가 없다. -> 가장 추천됨
Google guava 라이브러리 중 hash.Hashing
을 사용
캐싱을 사용해 불변 클래스의 해시 코드 계산 비용을 줄일 수 있다.