티스토리 뷰
[Effective Java] 09. equals를 재정의할 때는 반드시 hashCode도 재정의하라.
Reference M1 2019. 4. 24. 00:15
많은 버그가 hashCode 메서드를 재정의하지 않아서 생긴다. equals 메서드를 재정의하는 클래스는 반드시 hashCode 메서드도 재정의 해야 한다. 그렇지 않으면 Object.hashCode의 일반 규약을 어기게 되므로 HashMap, HashSet, Hashtable 같은 hash 기반 컬렉션과 함께 사용하면 오동작하게 된다.
일반 규약
같은 객체의 hashCode를 여러 번 호출하는 경우 equals가 사용하는 값이 변경되지 않았다면 언제나 동일한 정수(Integer)가 반환되어야 한다. 단 프로그램이 재시작되었을 경우 같은 값이 나올 필요는 없다.
- equals 메서드가 같다고 판정한 두 객체의 hashCode 값은 같아야 한다.
- equals 메서드가 다르다고 판정한 두 객체의 hashCode 값은 꼭 다를 필요는 없다. 그러나 서로 다른 hashCode 값이 나오면 Hashtable 성능이 향상될 수 있다.
중요한 점은 두 번째 규약이다. 만약 hashCode를 재정의 하지 않은 class를 HashMap을 사용하여 객체를 생성할 경우 입력했던 객체와 찾으려는 객체의 멤버 변수가 모두 동일하다고 해도 두 객체의 내용이 같을 뿐 별개의 객체이다.
따라서 hashCode는 다른 값을 반환하게 되고 HashMap에서 찾으려 해도 null 값만 반환하게 된다. 올바르진 않지만 그냥 문제없이 돌아가기만 하는 hashCode를 구현하기는 쉽다.
// 이렇게 구현하지 말자.
@Override
public int hashCode() {
return 42;
}
하지만 절대 이렇게 구현하면 안 된다.
특정 고정값으로 hashCode를 반환하면 두 번째 규약에 어긋나는 것은 아니다. 그런데 모두 같은 hash 값을 가지므로 그냥 리스트를 순차적으로 접근하여 해시 테이블은 결국 연결 리스트가 되어 버린다.
좋은 해시 함수는 다른 객체에는 다른 hashCode를 반환하는 경향이 있다. 일반 규약 세 번째 항목에서 언급한 사항이 바로 이것이다. 이상적인 해시 함수는 서로 다른 객체들을 모든 가능한 해시값에 균등하게 배분해야 한다.
JDK 1.7 이상이라면 Objects.hash() 또는 Apache 라이브러리 HashCodeBuilder를 사용하여 hashCode를 재정의 해줘야 한다.
'프로그래밍 > Effective Java' 카테고리의 다른 글
[Effective Java] 11. clone을 재정의 할때는 신중하라. (0) | 2019.06.10 |
---|---|
[Effective Java] 10. toString은 항상 재정의하라. (0) | 2019.04.28 |
[Effective Java] 08. equals를 재정의할 때는 일반 규약을 따르라. (0) | 2019.04.23 |
[Effective Java] 07. 종료자 사용을 피하라. (0) | 2019.04.21 |
[Effective Java] 06. 유효기간이 지난 객체 참조는 폐기하라. (0) | 2019.04.21 |
- 리액트 16
- 성능분석
- Maven
- 개발환경
- 오라클
- 제주도 여행
- 정렬 알고리즘
- effective java
- spring
- SQL
- 프로그래머스
- 리액트
- 자바스크립트
- 회고
- Java
- Linux 명령어
- javascript
- 소프트웨어공학
- 자바
- 오라클 내장 함수
- Eclipse
- 프로그래머
- 경력관리
- 리눅스 명령어
- Collection
- sort algorithm
- 이직
- 제주도 3박4일 일정
- React
- Tomcat
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 |
30 | 31 |