What is the use of hash codes in Java? Java uses hash codes for the same reason described above—to efficiently retrieve data from hash based collections. If the objects of your class are not used as keys in a hash based collection, for example, in a Hashtable, HashMap, etc., you need not even worry about hash codes for your objects at all.
You can compute hash code for an object in Java. In case of an object, the pieces of information that will be used to compute the hash code are the pieces of information that make up the state of the object. Java designers considered the hash code for an object so important that they provided a default implementation to compute the hash code for an object in the Object class.
The Object class has a hashCode() method that returns an int, which is the hash code of the object. The default implementation of this method computes the hash code of an object by converting the memory address of the object into an integer. Since the hashCode() method is defined in the Object class, it is available in all classes in Java. However, you are free to override the implementation in your class. Here are the rules that you must follow when you override the hashCode() method in your class. Suppose there are two object references, x and y.
If x.equals(y) returns true, x.hashCode() must return an integer, which is equal to y.hashCode(). That is, if two objects are equal using the equals() method, they must have the same hash codes.
If x.hashCode() is equal to y.hashCode(), it is not necessary that x.equals(y) returns true. That is, if two objects have the same hash codes using the hashCode() method, they do not have to be equal using the equals() method.
If the hashCode() method is called on the same object multiple times in the same execution of a Java application, the method must return the same integer value. The hashCode() and equals() methods are closely tied. If your class overrides any of these two methods, it must override both for the objects of your class to work correctly in hash-based collections. Another rule is that you should use only those instance variables to compute the hash code for an object, which are also used in the equals() method to check for equality.
If your class is mutable, you should not be using objects of your class as keys in hash-based collections. If the object has been used as a key changes after their use, you will not be able to locate the object in the collection because locating an object in a hash based collection is based on its hash code. In such cases, you will have stranded objects in the collection.
How should you implement a hashCode() method for a class? Here are some guidelines to write the logic for the hashCode() method for your class, which is reasonable for most of the purposes:
Start with a prime number, say 37.
int hash = 37;
Compute the hash code value for each instance variable of primitive data types separately using the following logic. Note that you need to use only those instance variables in the hash code computation, which are also part of the equals() method logic. Let’s store the result of this step in an int variable code. Let’s assume that value is the name of the instance variable.
For byte, short, int, and char data types, use their integer value as
code = (int)value;
For long data type, use the XOR for two halves of 64-bit as
code = (int)(value ^ (value >>>32));
For float data type, convert its floating-point values to an equivalent integer value using
code = Float.floatToIntBits(value)
For double data type, convert its floating-point value to long using the doubleToLongBits() method of the Double class and then convert the long value to an int value using the procedure as described above for the long data type.
long longBits = Double.doubleToLongBits(value);
code = (int)(longBits ^ (longBits >>>32));
For boolean data type, use 1 for true and 0 for false.
code = (value ? 1 : 0)
For a reference instance variable, use 0 if it is null. Otherwise, call its hashCode() method to get its hash code. Suppose ref is the name of the reference variable.
code = (ref == null ? 0: ref.hashCode());
Compute the hash code using the following formula. Using 59 in the formula is an arbitrary decision. Any other prime number, say 47, will work fine.
hash = hash * 59 + code;
Repeat the above three steps for all instance variables you want to include in your hashCode() computation.
Finally, return the value contained in the hash variable from your hashCode() method.
The above method is one of the many ways, not the only way, to compute hash code of an object in Java. Consult a good textbook on computing hash codes if you need a stronger hash function. All primitive wrapper classes and String class override the hashCode() method to provide reasonably good implementations of hash functions.
Tip Java 7 added a utility class java.lang.Objects. It contains a hash() method that computes the hash code for any number of values of any type. From Java 7, you are advised to use the Objects.hash() method to compute the hash code of an object. Please refer to “The Objects Class” section later in this chapter for more details.