1. equals method indicates whether some other object is "equal to" this one.
2. hashCode method returns a hash code value for the object, which is unique for unequal objects.
The equals method and hashCode method for any java class should go hand in hand. Any variable contributing to equals method must also be used for hashCode calculation because as per definition Objects having same hashCode should be equal to each other or conversely no two different objects may have the same hashCode.
hashCode values may also be inserted into the database as passwords and when user enters password in the application, its hashCode can be compared with the value in password field. Thus hashCode can also help with data encryption.
Here is an example on how to implement these methods.
/*
  *   @(#)Employee.java       1.1   11/05/09
  *
  *   Copyright   2009   Lazy   Coder.   All   rights   reserved.
  *   To   be   used   only   for   educational   purposes.
  *   Not   to   be   reproduced   and   published
  *   without   seeking   prior   consent.
  */
package   com.lazy.coder.examples;
/**
  *  
  *   @author   lazycoder
  *
  */
public   class   Employee   {
       private   int   empId;
       private   String   empName;
       public   boolean   equals(Object   obj)   {
              //If   this   object   and   the   Object   in   the   argument   refer   to   same   object   return   true.
              if   (this   ==   obj)
                     return   true;
              //If   obj   is   null   or   of   some   other   class   return   false.
              if   ((obj   ==   null)   ||   (obj.getClass()   !=   this.getClass()))
                     return   false;
              //   object   must   be   of   type   Employee   now
              Employee   emp   =   (Employee)   obj;
              //If   empId   =   obj.emoId   and   empName.equals(obj.empName)   return   true   else   false.
              return   empId   ==   emp.empId
                            &&   (empName   ==   emp.empName   ||   (empName   !=   null   &&   empName
                                          .equals(emp.empName)));
       }
       public   int   hashCode()   {
              int   result   =   17;
              result   =   37   *   result   +   empId;
              result   =   37   *   result   +   (empName   ==   null   ?   0   :   empName.hashCode());
              return   result;
       }
}
Here are a few tips on how to override these methods:
I. hashCode
- Store some arbitary constant nonzero integer value, say 17, in an int variable called result.
- For each significant field f in your object (each field taken into account by the equals( ) method), calculate an int hash code c for the field in the following manner:
Field type | Calculation |
boolean | c = (f ? 0 : 1) |
byte, char, short, or int | c = (int)f |
long | c = (int)(f ^ (f >>>32)) |
float | c = Float.floatToIntBits(f); |
double | long l = Double.doubleToLongBits(f); |
Object, where equals( ) calls equals( ) for this field | c = f.hashCode( ) |
Array | Apply above rules to each element |
- Combine the hash code(s) computed above:
result = 37 * result + c;
where 37 can be replaced with any primary number - Return result.
- Look at the resulting hashCode( ) and make sure that equal instances have equal hash codes.
equals
- Use the equality
==
operator to check if the argument is the reference to this object, if yes. return true. This saves time when actual comparison is costly. - Check that the argument is not
null
and it is of the correct type, if not then returnfalse
.
Note that, correct type does not mean the same type or class. It could be any class or interface that one or more classes agree to implement for providing the comparison. - Compare significant variables of both, the argument object and this object and check if they are equal. If *all* of them are equal then return true, otherwise return false. Again, as mentioned earlier, while comparing these class variables; primitive variables can be compared directly with an equality operator (
==
) after performing any necessary conversions (Such as float toFloat.floatToIntBits
or double toDouble.doubleToLongBits
). Whereas, object references can be compared by invoking theirequals
method recursively. You also need to ensure that invokingequals
method on these object references does not result in aNullPointerException
. - Do not change the type of the argument of the
equals
method. It takes ajava.lang.Object
as an argument, do not use your own class instead. If you do that, you will not be overriding theequals
method, but you will be overloading it instead; which would cause problems.
Your uniqueness comments regarding hashcodes is wrong. Equal objects should have equal hashcodes. But, two objects with equal hashcodes are not necessarily equal objects.
ReplyDeleteA hashcode is an int.
But, for example, a java.lang.Long object has a hashcode. Since there are more Long values than there are int values, multiple Long values must have the same hashcode. This is an example of the Pigeonhole Principle: http://en.wikipedia.org/wiki/Pigeonhole_principle
Each pigeonhole here is a single 'int' value that could be returned from a hashCode method.