Steps to construct a hash code method

 

[ Adopted from "Effective Java" by Joshua Bloch, ©2001 Addison–Wesley, pp. 36–41 ]

Use the same fields in constructing a hash code as are used in the (overloaded) equals method.  This is required!

For each such field, calculate a hashcode just for that field (let's call them fieldHash1, fieldHash2, ...).  The way the field hash code is calculaed depends on the type of the field f :

field hash code calculations
type of field   hash code formula
boolean   fieldHash = f ? 0 : 1
any integer type except long   fieldHash = (int) f
long   fieldHash = (int) (f ^ (f >>> 32))
float   fieldHash = Float.floatToIntBits( f )
double   int v=Double.doubleToLongBits(f)
fieldHash = (int) (v ^ (v >>> 32))
any Object reference   fieldHash = f.hashCode()

For collections or arrays, treat each item as a separate field.

Finally, combine the obtained fieldHash values into the result so far.  The result should be initialized to a random value.  Experience has shown that prime numbers work well, something like:

   int result = 17;

To combine each file hash code into the result:

   result = 37 * result + fieldHash1;
   result = 37 * result + fieldHash2;
   result = 37 * result + fieldHash3;
   ...
   return result;

Example: trivial class Person

class Person
{
   private final String lastName, firstName;
   private int age;
   private final long SSN;

   ...

   public boolean equals (Object o )
   {  if ( o instanceof Person )  // Note this is false if o == null
      {  Person p = (Person) o;
         return (this.lastName.equals(p.lastName) &&
                 this.SSN == p.SSN);
      }
      return false;
   }

   public int hashCode ()
   {
      int result = 17;  // 17 is an arbitrary value
      result = 37 * result + (int) (SSN ^ (SSN >>> 32))  // so is 37
      result = 37 * result + lastName.hashCode();
      return result;
   }

Caching and lazy initialization of complex hash code

If a hash code for some object seems time consuming to compute, you may not use it at all, or you may need it many times.  The way to deal with this situation is known as lazy initialization.  Basically, you only calculate the value once, the first time the hashCode method is invoked on that object.  Once calculated you store the hash code in a property:

class Foo
{
   ...
   private volatile int hashCode = 0;

   public int hashCode()
   {  if ( hashCode == 0 )
      {  int result = 17;  // 17 is arbitrary value
         result = 37 * result + field1hash;
         result = 37 * result + field2hash;
         ...
         hashCode = result;
      }
      return hashCode;
   }
}