728x90
hashCode 함수는 해시 테이블을 구축할 때 사용된다.
- 임의의 길이를 가진 데이터를 고정된 길이의 데이터로 변환(매핑)하는 것
- 이러한 과정을 해싱 한다고 하며, 해시함수에 얻어진 값을 보통 다이제스트(digest)라고 한다.
- 키 값의 무한성과 해시 함수 출력 값의 유한성 때문에 충돌이 일어날 수 있다.
가변성과 관련된 문제:
요소가 추가될 때만 해시 코드를 계산합니다.
요소가 변경되어도 해시 코드는 계산되지 않으며, 버킷 재배치도 이루어지지 않습니다.
그래서 기본적인 LinkedHashSet 와 LinkedHashMap 의 키 는 한번 추가한 요소를 변경할 수 없습니다.
=> 해시 기반 컬렉션에서는 키로 사용되는 객체가 불변이어야 한다. 키 객체가 변경 가능한 속성을 가진다면, 객체를 해시 테이블에 추가한 후에 그 속성을 변경하지 않아야 한다.
- hashCode 메서드의 규약:
- 일관성: 같은 객체에 대해 여러 번 호출해도 같은 값을 반환해야 합니다. 객체의 상태가 변경되지 않는 한, hashCode는 항상 같은 값을 반환해야 합니다.
- 동일성: 두 객체가 equals 메서드로 비교했을 때 같다면, 같은 hashCode를 반환해야 합니다. a.equals(b) == true이면 a.hashCode() == b.hashCode()도 true여야 합니다.
- 동일하지 않음: 두 객체가 equals 메서드로 비교했을 때 다르다고 해서 반드시 다른 hashCode를 반환할 필요는 없습니다. 하지만 다른 객체에 대해서는 가능한 한 다른 hashCode 값을 반환하는 것이 좋습니다. a.equals(b) == false이면 a.hashCode() != b.hashCode()가 반드시 참일 필요는 없지만, 다르게 구현하는 것이 성능에 유리합니다.
- hashCode 메서드 구현 시 주의사항:
- 중요한 필드 사용: 객체의 중요한 필드를 사용하여 고유한 해시코드를 생성합니다.
- 불변성 보장: 객체의 상태가 변경되지 않는 한, 같은 해시코드를 반환하도록 보장합니다.
- 충돌 최소화: 서로 다른 객체가 같은 해시코드를 가질 확률을 최소화하도록 해시코드를 생성합니다.
- hashCode 메서드 구현 예시:
data class Person(val name: String, val age: Int) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
other as Person
return name == other.name && age == other.age
}
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + age
return result
}
}
hashCode 를 구현할 때는 equals와 일관된 결과가 나와야 한다.
728x90
'공부 > 이펙티브코틀린' 카테고리의 다른 글
아이템 43 - API 의 필수적이지 않는 부분을 확장 함수로 추출하라 (0) | 2024.08.10 |
---|---|
아이템 42 - compareTo 의 규약을 지켜라 (0) | 2024.08.10 |
아이템 40 - equals 의 규약을 지켜라 (0) | 2024.08.01 |
아이템39 - 태그 클래스보다는 클래스 계층을 사용하라 (0) | 2024.08.01 |
아이템 38 - 연산 또는 액션을 전달할 때는 인터페이스 대신 함수 타입을 사용하라 (0) | 2024.08.01 |
댓글