For a class whose fields are solely primitive, ex.:
class Foo
{
int a;
String b;
boolean c;
long d;
boolean equals(Object o)
{
if (this == o) return true;
if (!(o instanceof Foo)) return false;
Foo other = (Foo) o;
return a == other.a && b.equals(other.b) && c == other.c && d = other开发者_C百科.d;
}
}
Is this a reasonably "good enough" way to write hashCode()
?
boolean hashCode()
{
return (b + a + c + d).hashCode();
}
That is, I construct a String
out of the same fields that equals()
uses, and then just use String#hashCode()
.
Edit: I've updated my question to include a long
field. How should a long
be handled in hashCode()
? Just let it overflow int
?
Your hash code does satisfy the property that if two objects are equal, then their hash codes need to be equal. So, in that way it is 'good enough'. However, it is fairly simple to create collisions in the hash codes which will degrade the performance of hash based data structures.
I would implement it slightly differently though:
public int hashCode() {
return a * 13 + b.hashCode() * 23 + (c? 31: 7);
}
You should check out the documentation for the hashCode()
method of Object
. It lays out the things that the hash code must satisfy.
It totally depends on what your data will look like. Under most circumstances, this would be a good approach. If you'll often have b
end with a number, then you'll get some duplicate codes for unequal objects, as JacobM's answer shows. If you know ahead of time that b will pretty much never have a number value at the end, then this is a reasonable hashing algorithm.
精彩评论