Value-based classes have the property that they
are final and immutable (though may contain references to mutable objects).
Consequently, if you know that your object only contains immutable instances, you could precompute the hashCode
of the instance. This could speed up access when using Map
or Set
operations.
Looking at the implementation of hashCode
from Instant
, which is a value-based class, why have the developers decided against this pattern? Would the loss of performance for precomputing the hashCode
be more significant than computing it over and over again when required?
// copied from Instant#hashCode
@Override
public int hashCode() {
return ((int) (seconds ^ (seconds >>> 32))) + 51 * nanos;
}
So, under what condition is precomputing the hashCode
justified?
The easiest way to compute a field's hash code is to just call `hashCode` on it. Combining them could be done manually.
The value 31 was chosen because it is an odd prime. If it were even and the multiplication overflowed, information would be lost, as multiplication by 2 is equivalent to shifting. The advantage of using a prime is less clear, but it is traditional.
Java equals() and hashCode() methods are present in Object class. So every java class gets the default implementation of equals() and hashCode().
Value-based classes, as defined in the Java docs, are classes which conform to a set of rules: - are final and immutable (though may contain references to mutable objects);
There isn't straight-forward reason why Instant
doesn't cache hashcode
. But some that I could think of:
Caching hashcode
comes at a price: the instance variable declared:
hashcode
may never be called on an Instant object. In such a case, we waste CPU in computing something that is never usedSo may not make sense to cache. May be it makes sense for String
as it is so commonly used throughout. May be worth the headache.
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