Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.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?

like image 240
Matt Ball Avatar asked Dec 14 '10 17:12

Matt Ball


People also ask

Should you override hashCode?

You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object. hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.

What would happen if I only override hashCode?

Only Override HashCode, Use the default Equals: Only the references to the same object will return true. In other words, those objects you expected to be equal will not be equal by calling the equals method. Only Override Equals, Use the default HashCode: There might be duplicates in the HashMap or HashSet.

Does overriding the hashCode () method have any performance implication?

overriding doesn't add much overhead, if at all. The efficiency of your hashCode() implementation is up to what it has to do and how you write it. You could cache the value if it's important to you.

What happens if we don't override hashCode method?

If you don't override hashcode() then the default implementation in Object class will be used by collections. This implementation gives different values for different objects, even if they are equal according to the equals() method.


1 Answers

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.

like image 164
jjnguy Avatar answered Oct 14 '22 13:10

jjnguy