HashCode and equals methods

SHARE & COMMENT :

HashTable, HashMap and HashSet are the Collection classes in java.util package that make use of hashing algorithm to store objects. In all these Collection classes except HashSet, objects are stored as key-value pairs. For the storage and the retrieval of any user-defined objects it is a good practice to override the following methods which is mentioned below,

  • hashCode()
  • equals()

These methods are available in the Object class and hence available to all java classes.Using these two methods, an object can be stored or retrieved from a Hashtable, HashMap or HashSet.

also read:

hashCode() method

This method returns a hashcode value as an int for the object. Default implementation for hashcode() should be overridden in order to make searching of data faster. The implementation of hashCode() method for an user-defined object should be calculated based on the properties of the class which we wish to consider.

equals() method

This method returns a boolean which specifies whether two objects are equal or not. The default implementation of equals() method given by the Object Class uses the ‘==’ operator to compare two object references, and returns true only if they refer to the same object. But, we can meaningfully re-define this equals() method to have en equality check based on our own criteria.
Consider the following code, which defines two user defined classes Employee and EmployeeId which are supposed to be stored in a Map.

Employee.java

public class Employee {
	private String name;

	public Employee(String name) {
		this.name = name;
	}

	public String toString() {
		return name;
	}
}

EmployeeId.java

public class EmployeeId {
	private String id;

	public EmployeeId(String id) {
		this.id = id;
	}

	public String toString() {
		return id;
	}
}

The following class makes use of the above classes by storing it in a Map for later retrieval. We are adding Employee objects into the Map keyed with Employee Id.
HashCodeTest.java

public class HashCodeTest {
	public static void main(String[] args) {
		Map<employeeId, Employee>
		employees = new HashMap<employeeId, Employee>();
		employees.put(new EmployeeId("111"), new Employee("Johny"));
		employees.put(new EmployeeId("222"), new Employee("Jeny"));	// Line A
		employees.put(new EmployeeId("333"), new Employee("Jessie"));
		Employee emp = employees.get(new EmployeeId("222"));// Line B
		System.out.println(emp); // Line C
		}
	}
	}
}

In Line B, we try to retrieve the Employee object who has Employee Id with a value of 222. We expect the output to be ‘Jeny’, because the Employee with Employee Id (222) was already there in the Collection, but surprisingly, the output of the above code is null. The reason is that we did not override the equals() method for EmployeeId and Employee classes because the default implementation of equals() in the Object class considers the new EmployeeId("222") in the put statement and new EmployeeId("222") in the get statement as two different instances, and hence the call to get() in Line B returns null.
Let us look at how the same code works when we provide our desired implementation for hashcode() and equals() methods. We basically override hashcode() here just to make the object to be searched fast.

Employee.java

public class Employee {
	private String name;

	public Employee(String name) {
		this.name = name;
	}

	public String toString() {
		return name;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (obj.getClass() != getClass()) {
			return false;
		}
		Employee emp = (Employee) obj;
		if (this.name == emp.name) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		return name.hashCode();
	}
}

EmployeeId.java

public class EmployeeId {
	private String id;

	public EmployeeId(String id) {
		this.id = id;
	}

	public String toString() {
		return id;
	}

	public boolean equals(Object obj) {
		if (obj == null)
			return false;
		if (obj.getClass() != getClass()) {
			return false;
		}
		EmployeeId empId = (EmployeeId) obj;
		if (this.id == empId.id) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		return id.hashCode();
	}
}

Now, we get the desired output ‘Jeny’, because as per our implementation for the equals() method, the new EmployeeId("222") in the put statement and new EmployeeId("222") in the get statement are considered one and the same.

also read:

Comments

comments

About Krishna Srinivasan

He is Founder and Chief Editor of JavaBeat. He has more than 8+ years of experience on developing Web applications. He writes about Spring, DOJO, JSF, Hibernate and many other emerging technologies in this blog.

Comments

  1. Digvijay says:

    What if I want to use Integer in place of String in the EmployeeId Class constructor.

    • You need to do the changes in EmployeeId class as follows :

      public class EmployeeId {

      private Integer id;

      public EmployeeId(Integer id) {
      this.id = id;
      }

      public String toString() {
      return id.toString();
      }

      @Override
      public int hashCode() {
      // TODO Auto-generated method stub
      return id.hashCode();
      }

      @Override
      public boolean equals(Object obj) {
      // TODO Auto-generated method stub

      if (obj == null) {
      return false;
      }

      if (this.getClass() != obj.getClass()) {
      return false;
      }

      EmployeeId employeeId = (EmployeeId) obj;

      if (Integer.parseInt(this.id.toString()) == Integer.parseInt(employeeId.id.toString())) {
      return true;
      }
      return false;
      }
      }

  2. thnx.. cleared the doubts…

  3. Surya V says:

    What if I want to use Integer in place of String in the EmployeeId Class constructor.

     

  4. Satya Pandurangam says:

    Excellent explanation with example, key point to note is

    default implementation of equals() in the Object class considers the new EmployeeId(“222″)in the put statement and new EmployeeId(“222″) in the get statement as two different instances, and hence the call to get() in Line B returns null.

    This made to understand clear
    Good work man

  5. thanks for taking time and posting the content. Its good understanding.

  6. OfCourse you pointed to say how to elements get’s added to bucket using keys

  7. Abhishek Dewangan says:

    Thanks for giving such a nice content and example… Cleared all my doubt about equal() and hashCode() implementation…

  8. DeeNKHAN SAQI says:

    Super…..Good.,.SAQI

  9. Jayanth Babu says:

    In above first example “We basically override hashcode() here just to make the object to be searched fast
    We
    basically override hashcode() here just to make the object to be
    searched fast. – See more at:
    http://www.javabeat.net/2007/08/hashcode-and-equals-methods/#sthash.RnOrHsPK.dpuf
    We
    basically override hashcode() here just to make the object to be
    searched fast. – See more at:
    http://www.javabeat.net/2007/08/hashcode-and-equals-methods/#sthash.RnOrHsPK.dpuf” …I’m not getting this part ..What if i don’t override ?!

    We
    basically override hashcode() here just to make the object to be
    searched fast. – See more at:
    http://www.javabeat.net/2007/08/hashcode-and-equals-methods/#sthash.RnOrHsPK.dpuf

  10. Jayanth Babu says:

    I’m really not getting why we need to override hashcode …This works fine even without overriding hashCode() ….Guys help me out!

  11. Askari says:

    if empId.id == null, how can you handle it ?

    • It will return false in that case.

      • ok… If you have an object without his id (not from database) and another one with his id (from database). you’ll have a null pointer when doing id.hashcode(), isn’ it ?.

      • ok… If you have an object without his id (not from database) and another one with his id (from database). you’ll have a null pointer when doing id.hashcode(), isn’ it ?.

      • ok… If you have an object without his id (not from database) and another one with his id (from database). you’ll have a null pointer when doing id.hashcode(), isn’ it ?.

      • ok… If you have an object without his id (not from database) and another one with his id (from database). you’ll have a null pointer when doing id.hashcode(), isn’ it ?.

      • ok… If you have an object without his id (not from database) and another one with his id (from database). you’ll have a null pointer when doing id.hashcode(), isn’ it ?.

      • ok… If you have an object without his id (not from database) and another one with his id (from database). you’ll have a null pointer when doing id.hashcode(), isn’ it ?.

      • ok… If you have an object without his id (not from database) and another one with his id (from database). you’ll have a null pointer when doing id.hashcode(), isn’ it ?.

      • ok… If you have an object without his id (not from database) and another one with his id (from database). you’ll have a null pointer when doing id.hashcode(), isn’ it ?.

      • ok… If you have an object without his id (not from database) and another one with his id (from database). you’ll have a null pointer when doing id.hashcode(), isn’ it ?.

  12. different between hashcode() and equals() and toString() methods with examples please give answer.

  13. Meharaj fareedy says:

    Good Explanation… but when i using Integer in place of String i getting null…..
    can u please explain why this happen..

  14. most efficient comparison would be

    public boolean equals(Object obj) {
    if (obj == null)
    return false;
    if ((obj.getClass() !=this. getClass()) || obj.getEmployeeId()==null) {
    return false;
    }
    EmployeeId empId = (EmployeeId) obj;
    if (this.id == empId.id) {
    return true;
    }
    return false;
    }

Trackbacks

  1. […] in hexadecimal eg, zip @ 163b91, where zip would be the class name followed by the (@) sign and the hash code . Below is the pattern followed by toString in class […]

Speak Your Mind

*

Close
Please support the site
By clicking any of these buttons you help our site to get better