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.