hashCode And equals Methods Override

In this Java tutorial, we will discuss about hashCode, equals methods and what role they play in an object. Through this article we will find answer for the following questions,
  • What is the purpose of hashCode and equals methods?
  • How hashCode and equals are implemented?
  • Why hashCode should also be overridden when equals is overridden? 
 

equals Method

equals() method is used to determine the equality of two objects. To bring in little bit of Mathematics flavor lets see the properties of equality. When we say equality, it should adhere by the following properties,
  • Reflexive: Always, a = a. In Java, a.equals(a) should always be true.
  • Symmetric: If a = b, then b = a. In Java, if a.equals(b) is true, then b.equals(a) should be true.
  • Transitive: If a = b and b = c, then a = c. In Java, if a.equals(b) and b.equals(c) is true, then a.equals(c) should be true.
Above three points are some theory and do not worry about it much.
For a primitive type, determining the equality is simple. We all know an int value of 10 is always equal to 10. But this equals() method is about equality of two objects. When we say object, it will have properties. To decide about equality those properties are considered. It is not necessary that all properties must be taken into account to determine the equality and with respect to the class definition and context it can be decided. Then the equals() method can be overridden.

Override equals Method

Let us take an example scenario to understand equals() method and study how to override it in our custom implementation. We have a Tiger class and two instances of Tiger are equal if they have the same color and stripePattern is our definition of equality. In our example, though there is an additional property ‘height’, it is excluded from the equals definition to denote that it is entirely our choice.
 
package java;
 
public class Tiger {
  private String color;
  private String stripePattern;
  private int height;
 
  @Override
  public boolean equals(Object object) {
    boolean result = false;
    if (object == null || object.getClass() != getClass()) {
      result = false;
    } else {
      Tiger tiger = (Tiger) object;
      if (this.color == tiger.getColor()
          && this.stripePattern == tiger.getStripePattern()) {
        result = true;
      }
    }
    return result;
  }
 
  // just omitted null checks
  @Override
  public int hashCode() {
    int hash = 3;
    hash = 7 * hash + this.color.hashCode();
    hash = 7 * hash + this.stripePattern.hashCode();
    return hash;
  }
 
  public static void main(String args[]) {
    Tiger bengalTiger1 = new Tiger("Yellow", "Dense", 3);
    Tiger bengalTiger2 = new Tiger("Yellow", "Dense", 2);
    Tiger siberianTiger = new Tiger("White", "Sparse", 4);
    System.out.println("bengalTiger1 and bengalTiger2: "
        + bengalTiger1.equals(bengalTiger2));
    System.out.println("bengalTiger1 and siberianTiger: "
        + bengalTiger1.equals(siberianTiger));
 
    System.out.println("bengalTiger1 hashCode: " + bengalTiger1.hashCode());
    System.out.println("bengalTiger2 hashCode: " + bengalTiger2.hashCode());
    System.out.println("siberianTiger hashCode: "
        + siberianTiger.hashCode());
  }
 
  public String getColor() {
    return color;
  }
 
  public String getStripePattern() {
    return stripePattern;
  }
 
  public Tiger(String color, String stripePattern, int height) {
    this.color = color;
    this.stripePattern = stripePattern;
    this.height = height;
 
  }
}

Example Code Output:
bengalTiger1 and bengalTiger2: true
bengalTiger1 and siberianTiger: false
bengalTiger1 hashCode: 1398212510
bengalTiger2 hashCode: 1398212510
siberianTiger hashCode: –1227465966

hashCode Method

In the above example did you notice we have overridden another method hashCode() along with equals()? There is an importance to it. We must override hashCode() when we override equals(). Why hashCode should also be overridden when equals is overridden? Because, they both serve the same purpose but in different contexts.
hashCode() method is used in hashtables to determine the equality of  keys. If you want more details about hashCode, their default implementation, buckets, different hashing techniques you should go through my earliest tutorial on Java Hashtable. I guarantee you will enjoy, just read it :-).
When an application is executed, the hashcode (an integer) returned for an object should be same till another execution of that application. Now coming to the important point which is the contract between hashCode and equals method,
  • if two objects are equal, that is obj1.equals(obj2) is true then, obj1.hashCode() and obj2.hashCode() must return same integer.

Override hashCode Method

To honor the above contract we should always override hashCode() method whenever we override equals() method. If not, what will happen? If we use hashtables in our application, it will not behave as expected. As the hashCode is used in determining the equality of values stored, it will not return the right corresponding value for a key.
Default implementation given is hashCode() method in Object class uses the internal address of the object and converts it into integer and returns it. This is the lowest form of equality implementation and provides guaranteed results for hastables implementation. When we override equals() and change the meaning of equality for an object then the same should be reflected by overriding the hashCode method.
May be you should also go through String equals also at this juncture as String equality is one of the celebrated topic in Java.







0 comments:

Post a Comment