Best implementation for hashCode method for a collection
How do we decide on the best implementation of hashCode()
method for a collection (assuming that equals method has been overridden correctly) ?
Solution 1:
The best implementation? That is a hard question 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 (second edition). The best thing is to look it up there because the author explains there why the approach is good.
A short version
Create a
int result
and assign a non-zero value.-
For every field
f
tested in theequals()
method, calculate a hash codec
by:- If the field f is a
boolean
: calculate(f ? 0 : 1)
; - If the field f is a
byte
,char
,short
orint
: calculate(int)f
; - If the field f is a
long
: calculate(int)(f ^ (f >>> 32))
; - If the field f is a
float
: calculateFloat.floatToIntBits(f)
; - If the field f is a
double
: calculateDouble.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 iff == 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.
- If the field f is a
-
Combine the hash value
c
withresult
:result = 37 * result + c
Return
result
This should result in a proper distribution of hash values for most use situations.
Solution 2:
If you're happy with the Effective Java implementation recommended by dmeister, you can use a library call instead of rolling your own:
@Override
public int hashCode() {
return Objects.hashCode(this.firstName, this.lastName);
}
This requires either Guava (com.google.common.base.Objects.hashCode
) or the standard library in Java 7 (java.util.Objects.hash
) but works the same way.