Re: hashCode
On 8/10/2012 6:22 PM, bob smith wrote:
[... many blank lines removed for legibility's sake ...]
On Friday, August 10, 2012 11:34:28 AM UTC-5, Eric Sosman wrote:
On 8/10/2012 11:47 AM, bob smith wrote:
Is it always technically correct to override the hashCode function like so:
@Override
public int hashCode() {
return 1;
}
Would it be potentially better if that was Object's implementation?
Define "better."
Better in the sense that you would never HAVE to override hashCode.
Now, there are cases where you HAVE to override it, or your code is very broken.
I cannot think of a case where you HAVE to override hashCode(),
except as a consequence of other choices that you didn't HAVE to
make. You don't HAVE to invent classes where distinct instances
are considered equal, and even if you do you don't HAVE to put those
instances in HashMaps or HashSets or whatever.
But that's a bit specious: All it says is that you don't HAVE
to override hashCode() because you don't HAVE to use things that
call it. It's like "You don't HAVE to pay taxes, because you don't
HAVE to live outside prison." So, let's take it as a given that
you will often need to write classes that override equals() and
hashCode() -- I imagine you understand that they go together.
Okay: Then returning a constant 1 (or 42 or 0 or whatever)
would in fact satisfy the letter of the law regarding hashCode():
Whenever x.equals(y) is true, x.hashCode() == y.hashCode(). In
your example this would be trivially true because x,y,z,... all
have the same hashCode() value, whether they're equal or not --
You have lived up to the letter of the law.
Of course, such a hashCode() would make all those hash-based
containers pretty much useless: They would work in the sense that
they would get the Right Answer, but they'd be abominably slow,
with expected performance of O(N) instead of O(1). See
<http://www.cs.rice.edu/~scrosby/hash/CrosbyWallach_UsenixSec2003/>
for a survey of some denial-of-service attacks that work by driving
hash tables from O(1) to O(N), resulting in catastrophic failure
of the attacked system.
In other words, the letter of the law on hashCode() is a bare
minimum that guarantees correct functioning, but it is not enough
to guarantee usability. Why isn't the law more specific? Because
nobody knows how to write "hashCode() must be correct *and* usable"
in terms that would cover all the classes all the Java programmers
have dreamed up and will dream up. Your hashCode() meets the bare
minimum requirement, but is not "usable." The actual hashCode()
provided by Object also meets the bare minimum requirement, and *is*
usable as it stands, until (and unless; you don't HAVE to) you
choose to implement other equals() semantics, and a hashCode() to
match them.
--
Eric Sosman
esosman@ieee-dot-org.invalid