I just read in Effective Java about the hashCode
method:
Store some constant nonzero value, say, 17, in an int variable called result.
For each significant field f in your object (each field taken into account by the equals method, that is), do the following:
a. Compute an int hash code c for the field.
b. Combine the hash code c computed in step 2.a into result as follows:
result = 31 * result + c;
A nonzero initial value is used in step 1 so the hash value will be affected by initial fields whose hash value, as computed in step 2.a, is zero.
If zero were used as the initial value in step 1, the overall hash value would be unaffected by any such initial fields, which could increase collisions. The value 17 is arbitrary. The multiplication in step 2.b makes the result depend on the order of the fields, yielding a much better hash function if the class has multiple similar fields.
And that's their implementation of hashCode
:
@Override public int hashCode() {
result = 17;
result = 31 * result + areaCode;
result = 31 * result + prefix;
result = 31 * result + lineNumber;
hashCode = result;
return result;
}
My questions are below:
- How does the initial value 17 help us decrease collisions?
- How does multiplying by 31 help us decrease collisions?
- Why do we use 17 and 31? I know they are prime numbers. Is that why we use them?
I tried to come up with an example of a collision using a class with two and three integer fields, but didn't succeed. I'd glad, if you gave me a simple example of a collision.