Is there a standard meta-algorithm or best practice of how to implement the hashCode() method for classes that are composed of other classes:
class A { B b; C c; ... }
If we assume that B and C put some effort in implementing their hashCode(), it is certainly a good idea to base As hashcode on that of B and C. But how to best combine them?
I ask this because certain operations are obviously not well suited like in:
class Naive {
B b1, b2;
public int hashCode() { return b1.hashCode() ^ b2.hashCode(); }
}
This would cause a hash code of 0 for every Naive object that happens to have two equal B objects.
This is a common pattern, which some Eclipse plug-ins are able to generate:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((b1 == null) ? 0 : b1.hashCode());
result = prime * result + ((b2 == null) ? 0 : b2.hashCode());
// repeat for other attributes you want to include...
return result;
}
Don't forget to code the equals() method accordingly...
nwinkler's algorithm (which is in fact what would be generated by Eclipse when using the Source > Generate hashcode and equals... functionality) is similar to what Joshua Bloch describes in Effective Java (as referenced in Puce's answer).
The idea is to combine hashcodes computed for significant fields. The use of the odd prime number 31 can result in a jvm optimization of the multiplication (into a shift + substraction). Note that you must exclude fields that are not used in equals() from this hashcode computation. You may exclude fields whose values are computed from fields included in the computation.
The suggested hashcode computation for an Object field is simply to recursively call its hashcode method, provided it is not null (in which case we use 0) and the object's equals() method is itself recursively called in our equals() method. If the latter is not the case (equals does a more complex comparison on our object field), suggested approach is to construct a canonical representation and compute an hashcode for it.
To compute an hashcode for primitive fields, following methods are suggested (note that they must still be combined into the result by doing result = result * prime + fieldHashCode):
Float.floatToIntBits(f)(int) f(int) (f ^ (f>>>32))(f?1:0)longHash= Double.doubleToLongBits(f) then use (int) (longHash^(longHash>>>32))If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With