Of Object, equals (), == and hashCode ()

By: Girish Manwani Viewed: 192 times  Printer Friendly Format    


By now we all have heard it over and over again – In java except primitives, everything is an Object. Object class stands at the top of the hierarchy. This means every class has Object as its super class at the top and hence every subclass contains the default implementation of Object’s methods .Object contains 2 very important methods equals () and hashCode ().Lets step through these important methods one by one.

Let’s look at the default implementation of equals () in Object class,

public boolean equals (Object obj)
{
       return this == obj;
}

Duh! that’s as simple as anything can ever get. The equal’s method is comparing the reference of an object instance with another object instance. If the two instances point to the same location in memory the method will return true, else false. This means if we created two identical instances of a class that we would like to be true – it will not be the case unless the two instances pointed to the same location in memory.

How can we change this?
A closer look at the method signature suggests one important point. Like most other methods in the Object class the method is public and can be overridden to change the functionality. Let’s take a real world example to explain why this is required.

Consider we have an Instrument class which has various security attributes including a unique CUSIP number. Every security will have a unique cusip.

public class Instrument {

       private String cusip = \"\";

       public Instrument (String cusip){
               this.cusip = cusip;

       }

/**
        * @return the cusip
        */
       public String getCusip () {
               return cusip;
       }

// few other methods…

}
Now let’s look at the perils of not overriding the equal’s method.
Add the main method to Instrument class as below,

public static void main (String args [])        {

       Instrument i1 = new Instrument (\"123456789\");
       Instrument i2 = new Instrument (\"123456789\");

       System.out.println (\"i1 equals i2 test ::\"+( i1.equals (i2)));

}

Here i1.equals (i2) prints false.

In the above scenario the equals method is overridden to compare the cusip numbers and hence the equality tests fails.

Overriding equals can change this.

/* check for object equality
 * @see java.lang.Object#equals(java.lang.Object)
 */
public boolean equals(Object obj) {
       if (this == obj)
               return true;
       if (obj == null)
               return false;
       if (getClass() != obj.getClass())
               return false;
       final Instrument other = (Instrument) obj;
       if (cusip == null) {
               if (other.cusip != null)
                       return false;
       } else if (!cusip.equals(other.cusip))
               return false;
       return true;
}

In our new equals method above we do string comparison using String’s equals method.Fotunately for us The String class in Java overrides the equals method. The String class’s equal method compares the content of the cusip string for the two instances and returns true.

hashCode () goes hand in hand.

According to the general contract for hashCode – If two objects are equal according to the equals method then the hashCode must return the same integer value. It means that equal objects must produce the same hashCode as long as they are equal.




Let’s look at how this can be implemented in our class.

/* generates unique integer value for equal object instances
 * @see java.lang.Object#hashCode()
 */
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((cusip == null) ? 0 : cusip.hashCode());
return result;
}


Let’s look at how hashCode is implemented here. For non-null cusips the cusip strings hashCode is multiplied by any arbitrary prime number to produce a value for hashCode.This value will not change for same cusip string because cusip’s hasdhCode is used to produce the result.

Here is a complete listing of the code.

public class Instrument {

       private String cusip = \"\";

       public Instrument(String cusip){
               this.cusip = cusip;
       }

       /**
        * @return the cusip
        */
       public String getCusip() {
               return cusip;
       }

       public static void main(String args[])  {

               Instrument i1 = new Instrument(\"123456789\");
               Instrument i2 = new Instrument(\"123456789\");

               System.out.println(\"i1 equals i2 test ::\"+(i1.equals(i2)));

       }

       /* generates unique integer value for equal object instances
        * @see java.lang.Object#hashCode()
        */
       public int hashCode() {
               final int PRIME = 31;
               int result = 1;
result = PRIME * result + ((cusip == null) ? 0 : cusip.hashCode());
               return result;
       }

       /* check for object equality
        * @see java.lang.Object#equals(java.lang.Object)
        */
       public boolean equals(Object obj) {
               if (this == obj)
                       return true;
               if (obj == null)
                       return false;
               if (getClass() != obj.getClass())
                       return false;
               final Instrument other = (Instrument) obj;
               if (cusip == null) {
                       if (other.cusip != null)
                               return false;
               } else if (!cusip.equals(other.cusip))
                       return false;
               return true;
       }
       }

Url: http://www.scribd.com/doc /348686/Of-Object-equals-and -hashCode-



Most Viewed Articles (in Java )

Latest Articles (in Java)

Comment on this tutorial