equals 메서드를 재정의하는 클래스는 반드시 hashCode 메서드도 재정의 해야 한다. 그렇지 않으면 hashCode의 일반 규약을 어기게 되므로 해시기반 컬렉션과 함께 사용하면 오동작하게 된다.
실행중에 hashCode를 여러 번 호출하는 경우, equals가 사용하는 정보들이 변경되지 않았다면, 언제나 동일한 정수가 반환되어야 한다.
equals 메서드가 같다고 판정한 두 객체의 hashCode 값은 같아야 한다.
equals 메스더가 다르다고 판정한 두 객체의 hashCode 값은 꼭 다를 필요는 없다.
쓸만한 hashCode 만드는 법
1. 0이 아닌 상수를 result라는 이름의 int 변수에 저장한다.
2. 객체 안에 있는 모든 중요 필드 f에 대해서 아래의 절차를 시행한다.
A).
1)필드가 boolean이면 (f ? 1 : 0)을 계산한다.
2)필드가 byte,char,short,int 중 하나면 (int)f 를 계산한다.
3)필드가 long이면 (int)(f^f>>>32)를 계산한다.
4)필드가 float이면 Float.floatToIntBits(f) 를 계산
5)필드가 double이면 Double.doubleToLongBits(f) 를 계산하고 그 결과로 얻은 long 값을 위의 절차 3) 을 따라서 해시 코드로 변환한다.
6)필드가 객체 참조이고 equals 메서드가 해당 필드의equals 메서드를 재귀적으로 호출하는 경우에는 해당 필드의hashCode 메서드를 재귀적으로 호출하여 해시 코드를 계산한다.
7)필드가 배열인 경우에는 배열의 각 원소가 별도 필드인 것처럼 계산한다.
B). 절차 A에서 계산된 해시코드 c를 result에 다름과 같이 결합한다.
result = 31 * result + c
4.구현이 끝났다면 동치 관계에 있는 객체의 해시 코드값이 똑같이 계산되는 지 비교.
hashCode를 명시적으로 42와 같이 지정하지 않는 이유는?
해당 클래스의 모든 객체가 같은 해시코드를 갖기때문에 전부 같은 버킷에 해시되므로, 해시 테이블의 성능이 엄청나게 안좋아진다.
'개발서적 > 이펙티브자바' 카테고리의 다른 글
[모든 객체의 공통 메서드]규칙11.clone을 재정의할 때는 신중하라 (0) | 2017.04.19 |
---|---|
[모든 객체의 공통 메서드]규칙10.toString은 항상 재정의하라 (0) | 2017.04.19 |
[모든 객체의 공통 메서드]규칙8.equals를 재정의할 때는 일반 규약을 따르라. (0) | 2017.04.18 |
[객체의 생성과 삭제]규칙7.종료자 사용은 피하라 (0) | 2017.04.17 |
[객체의 생성과 삭제]규칙6. 유효기간이 지난 객체 참조는 폐기하라. (0) | 2017.04.16 |