开发者

Overriding hashCode() - is this good enough?

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜