In this article we will be discussing about what is equals() and hashcode() method defined in Object class in java along with why is it required to override them. We will also take a look into how to override these methods, the contract between equals() and hashcode() method, things to remember while overriding equals() and hashcode() and about different automatic ways to generate overriden methods.
What is equals() and hashcode()
Both of these are methods defined in java.lang.Object
class. We use equals() method to compare if two objects are meaningfully equivalent means whether the two objects themselves(not the references) are equal(). To check whether the object references are equal or not, we use == operator which again uses object hash code value to evaluate it.
Coming to hashcode(), it is used to generate hash code value for an object and this hash code value is used by some collection classes to compare objects which in turn increases the performance of large collections of objects.
Let us define our Emplyee class for which we will be overriding the hashcode() and equals() method.
package com.devglan.core; public class Employee { private String name; private int age; private String address; public Employee(){} public Employee(String name, int age, String address) { this.age = age; this.name = name; this.address = address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
Why Overriding Equals() and Hashcode() is Required
First let us look into the default implementation of equals() in java.lang.Object class.
public boolean equals(Object obj) { return (this == obj); }
Above code sample shows that the default implementation only compares the object reference to decide whether an object is equal or not and these references are nothing but the hash code values which is generated by hashcode() method.So, unless you override equals() and hashcode() two objects are considered equal only if the two references refer to the same object and hence, there will be mismatch while using these objects as a key in any java collections.
For example let us create a map with key as an object and string as value as below. Populate it with some dummy entries. Now, create that same object with same set of prameters and try to fetch value from that map and see the output.
Following is an example.package com.devglan.core; import java.util.HashMap; import java.util.Map; public class HashcodeTest { public static void main(String [] args){ Map<Employee, String> empMap = new HashMap<Employee, String>(); Employee emp1 = new Employee("John", 23, "Bangalore"); Employee emp2 = new Employee("Max", 29, "Chennai"); empMap.put(emp1, "John details"); empMap.put(emp2, "Max details"); System.out.println(emp1); System.out.println(emp2); Employee emp3 = new Employee("John", 23, "Bangalore"); System.out.println(empMap.get(emp3)); } }
If you run above java class, you will see an output as below in the console
com.devglan.core.Employee@15db9742 com.devglan.core.Employee@6d06d69c null
Though that map has that object as a key but you got null because you have not overriden equals() and hashcode() and java is using its own default implementations to compare objects and generate hash codes and hence there is a mismatch. But if you override the equals() and hashcode() method you will get the perfect result as hashmap internally uses hashcode() method to generate hash code of any object and equals() method to check if those objects are meaningfully equal.
Other Interesting Posts Why wait(), notify(), notifyAll() Defined in Object class Comparable and Comparator in Java with Example Sorting HashMap by Key and Value Hello World Java Program Breakup Serialization and Deserialization in Java Convert hashmap to List in java
How to Override HashCode Method
Following is the sample code we added in the Emplyee class to override the hashcode() method
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (name == null ? 0 :name.hashCode()); result = prime * result + age; result = prime * result + (address == null ? 0 : address.hashCode()); return result; }
Here the idea to use 31 as hash is just to ensure distinct hashcode for distinct object. You need to calculate hash for different memeber and return the total as a unique hash code.
How to Override Equals() Method
Following is the sample code we added in the Emplyee class to override the equals() method
@Override public boolean equals(Object obj){ if(obj == null){ return false; } if(obj instanceof Employee && this == obj) { return true; } Employee newEmp = (Employee)obj; if(age != newEmp.age) { return false; } if(name != null && !name.equalsIgnoreCase(newEmp.name)){ return false; } if(address != null && !address.equalsIgnoreCase(newEmp.address)){ return false; } return true; }
While overriding equals method, it is very much required to check for null
condition and proper object casting. We have used instanceof
check here before typecasting. Then we are checking whether each memebers of the object are meaningfully equivalent or not to another object. Based on this the final boolean result is evaluated.
Now, again you run the class HashcodeTest.java as a java application and you will get a perfect result as below:
com.devglan.core.Employee@8ac51512 com.devglan.core.Employee@93e7d68e John details
Equals and HashCode Contract
The hashcode() and equals() methods contract can be summarized as below;
1. If two objects are equal by equals() method then their hash code values must be same.
2. If two objects are not equal by equals() method then thier hash code may be same or different.
Automatic Generation of Equals() and HashCode()
The different IDE tools such as NetBeans, Eclipse, IntellijIdea have default support to generate hashcode() and equals() overriden methods. But sometimes that is not very useful. It completely depends on the data structure of your pojo.
SpringUtils has also support to override equals() and hashcode() methods but again that depends on the complexity.
Also there are is an opensource apache library that can override hashcode() and equals() method.
Conclusion
I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.