Prime Number 17
2025. 4. 23. 17:12ㆍHigh Level Programming Language/Learning the Java Language
자바에서 hashCode()
메서드 오버라이딩 시 흔히 사용되는 초기값 17
역시 단순한 임의의 숫자가 아니라, 컴퓨터 과학적·실무적 맥락에서 깊은 의미와 역할을 갖습니다.
🎯 핵심 요약
hashCode()
의 초기값으로 17
을 사용하는 이유는, 해시코드 조합의 출발점을 예측 불가능하게 만들고, 필드 해시코드들의 충돌 가능성을 낮추기 위한 시드(seed) 역할을 하기 때문입니다.
📌 1. 해시코드에서 초기값의 역할은 무엇인가?
✅ 해시코드 누적 합산 방식
자바에서 다중 필드를 해시코드로 조합할 때는 다음과 같은 방식이 일반적입니다:
int result = INITIAL; // 초기값
result = 31 * result + field1; // 누적
result = 31 * result + field2;
...
✅ 초기값의 목적
- 항상 같은 필드 조합이라도, 초기값이 다르면 해시코드가 달라짐
- 초기값은 일종의 "시작점 시드(seed)" 역할을 하여 충돌 가능성을 줄이는 데 기여
🔢 2. 왜 하필 17
인가?
✅ 이유 1: 소수(Prime Number)
17
은 소수(prime number)입니다.- 해시코드 계산에서 소수를 사용하면, 특정 필드 조합이 비슷해도 충돌 가능성을 줄이는 효과가 있습니다.
- 필드 간 곱셈 인자(
31
)뿐만 아니라, 초기값 또한 소수를 사용함으로써 전체적으로 해시 함수의 품질을 높임
✅ 이유 2: 작은 수이면서도 너무 작지 않음
0
,1
,2
,7
등 너무 작은 수는 해시 분산 효과가 약하며, 패턴화된 결과를 만들 수 있습니다.17
은 적당한 크기의 정수로서, 성능 오버헤드 없이 예측 불가능성을 제공합니다.
✅ 이유 3: Effective Java의 표준 제안
Joshua Bloch의 저서 『Effective Java』에서는 다음의 초기값을 제안합니다:
Choose a nonzero odd number for initial result, preferably a prime like 17.
- 이는 오라클, 구글, 스프링, 안드로이드 등 수많은 코드베이스에서 채택한 사실상의 자바 해시코드 표준 관례입니다.
📘 예시: equals()
와 함께 쓰이는 전형적인 hashCode()
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + age;
return result;
}
17
→ 해시 누적의 출발점 (seed)31
→ 각 필드의 영향력을 차등 부여하기 위한 가중치 (weight)
🧠 3. 숫자 선택에 있어 고려된 조건
조건 | 의미 | 17이 적합한 이유 |
---|---|---|
소수 여부 | 충돌 확률 감소 | ✅ 소수 (prime) |
홀수 여부 | 2로 나누어지는 정수 생성 방지 | ✅ 홀수 |
적절한 크기 | 너무 작지도 크지도 않아야 함 | ✅ 적당한 크기 |
관례 | Java 커뮤니티에서 널리 사용됨 | ✅ 표준 관례 |
🚫 초기값으로 0을 사용하면 안 되는 이유?
int result = 0; // 초기값을 0으로 사용
result = 31 * result + field.hashCode(); // 0 * 31 == 0, 필드 해시만 반영
- 첫 필드의 해시코드가 전체 결과에 너무 지배적으로 작용함
- 다수의 객체가 동일한 해시코드를 갖게 될 위험 증가
- 즉, 초기값은 필드 조합에 의한 해시 다양성 확보를 위한 필수 요소
✅ 결론: 왜 17인가?
항목 | 설명 |
---|---|
소수(Prime) | 해시 분산성과 충돌 회피에 유리 |
홀수(Odd) | 짝수 연산으로 인한 패턴화 방지 |
작은 정수 | 계산 성능에 부담 없음 |
표준 관례 | Effective Java , 자바 표준 라이브러리에서 채택 |
📌 요약: 17
은 해시코드 설계의 품질, 예측불가성, 연산 효율성, 표준성 모두를 고려해 경량 고품질 초기값으로 이상적인 수입니다.
🔍 참고 사항
- 해시 충돌 분포 시뮬레이션 (해시 함수 성능 실험)
Objects.hash()
내부 구현 분석record
타입에서 hashCode 자동 생성 구조HashMap
의 hash 분산 구조 (spread()
함수)
'High Level Programming Language > Learning the Java Language' 카테고리의 다른 글
null은 왜 "모든 참조 타입의 하위"로 간주되는가? (1) | 2025.04.30 |
---|---|
Type Inference 알고리즘의 원칙: '후반부 결과'를 사용하지 않는 이유 (0) | 2025.04.30 |
Prime Number 31 (0) | 2025.04.23 |
equals() 메서드의 5대 계약 원칙 (0) | 2025.04.23 |
Object.equals() (0) | 2025.04.23 |