What is a best practice of writing hash function in java?

2022-09-01 01:56:54

I'm wondering what is the best practice for writing #hashCode() method in java. Good description can be found here. Is it that good?


答案 1

Here's a quote from Effective Java 2nd Edition, Item 9: "Always override when you override ":hashCodeequals

While the recipe in this item yields reasonably good hash functions, it does not yield state-of-the-art hash functions, nor do Java platform libraries provide such hash functions as of release 1.6. Writing such hash functions is a research topic, best left to mathematicians and computer scientists. [... Nonetheless,] the techniques described in this item should be adequate for most applications.

Josh Bloch's recipe

  • Store some constant nonzero value, say 17, in an variable called intresult
  • Compute an hashcode for each field that defines : intcfequals
    • If the field is a , compute boolean(f ? 1 : 0)
    • If the field is a , compute byte, char, short, int(int) f
    • If the field is a , compute long(int) (f ^ (f >>> 32))
    • If the field is a , compute floatFloat.floatToIntBits(f)
    • If the field is a , compute , then hash the resulting as in abovedoubleDouble.doubleToLongBits(f)long
    • If the field is an object reference and this class's method compares the field by recursively invoking , recursively invoke on the field. If the value of the field is , return 0equalsequalshashCodenull
    • If the field is an array, treat it as if each element is a separate field. If every element in an array field is significant, you can use one of the methods added in release 1.5Arrays.hashCode
  • Combine the hashcode into as follows: cresultresult = 31 * result + c;

Now, of course that recipe is rather complicated, but luckily, you don't have to reimplement it every time, thanks to java.util.Arrays.hashCode(Object[]).

@Override public int hashCode() {
    return Arrays.hashCode(new Object[] {
           myInt,    //auto-boxed
           myDouble, //auto-boxed
           myString,
    });
}

As of Java 7 there is a convenient varargs variant in java.util.Objects.hash(Object...).


答案 2

A great reference for an implementation of is described in the book Effective Java. After you understand the theory behind generating a good hash function, you may check HashCodeBuilder from Apache commons lang, which implements what's described in the book. From the docs:hashCode()

This class enables a good hashCode method to be built for any class. It follows the rules laid out in the book Effective Java by Joshua Bloch. Writing a good hashCode method is actually quite difficult. This class aims to simplify the process.


推荐