hashCode() 오버라이드
From : http://stackoverflow.com/questions/113511/hash-code-implementation
The best implementation? That is a hard questions because it depends on the usage pattern.
A for nearly all cases reasonable good implementation was proposed in Josh Bloch's "Effective Java" in item 8. The best thing is to look it up there because the author explains there why the approach is good.
A short version:
1) Create a int result and assign a non-zero value.
2) For every field tested in the equals-Method, calculate a hash code c by:
If the field f is a boolean: calculate (f ? 0 : 1);
If the field f is a byte, char, short or int: calculate (int)f;
If the field f is a long: calculate (int)(f ^ (f >>> 32));
If the field f is a float: calculate Float.floatToIntBits(f);
If the field f is a double: calculate Double.doubleToLongBits(f) and handle the return value like every long value;
If the field f is an object: Use the result of the hashCode() method or 0 if f == null;
If the field f is an array: See every field as separate element and calculate the hash value in a recursive fashion and combine the values as described next.
3) Combine the hash value c with result with:
result = 37 * result + c
4) Return result
This should result in a proper distribution of hash values for most use situations.
The number of 37 is arbitrary, but it should be prime. Why?
The reason for using prime numbers and the method described in this answer is to ensure that the computed hashcode will be unique. When using non-prime numbers, you cannot guarantee this. It does not matter which prime nummer you choose, there is nothing magical about the number 37
Well, computed hash code cannot be always unique :) Is a hashcode. However I got the idea: the prime number has only one multiplier, while non-prime has at least two. That creates an extra combination for multiplication operator to result the same hash, i.e. cause collision.
위의 안내에 따라서 Student 클래스의 hashCode() 메소드를 오버라이드한 결과는 다음과 같다
참고로, Eclipse 에서는 마우스 우측을 눌러 간편하게 아래의 공식을 적용한 hashCode()를 생성해주고 있으므로
아래의 코드처럼 직접 작성하는 경우는 별로 없을 것 같다
package test.java;
public class Student
{
private String name;
private int num;
public Student(String name, int num)
{
this.name = name;
this.num = num;
}
@Override
public String toString()
{
return name+"("+num+")";
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Student) {
Student st2 = (Student)obj;
if(this.getName().equals(st2.getName()) &&
this.getNum() == st2.getNum()) return true;
}
return false;
}
@Override
public int hashCode() {
int result = 1; // 0이 아닌 임의의 수
result = 37 * result + this.num; // 37은 임의의 소수
result = 37 * result + (this.name==null ? 0 : this.name.hashCode()); // equals()로 비교되는 모든 멤버변수의 값을 hash 값에 반영한다
return result;
}
public String getName()
{
return name;
}
public int getNum()
{
return num;
}
}