Always override hashcode when you override equals
This is a piece of advice from Joshua Bloch on Effective Java book.
You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object.hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.
Explanation with code:
Hash-based collections, such as HashMap, HashSet, and Hashtable use a hashcode value of an object to determine how it should be stored inside a collection. The hashcode is used in order to locate the object in its collection.
Retrieval from hash-based collections is a two-step process:
- Find the right bucket (using hashCode())
- Search the bucket for the right element (using equals() )
Lets check why we should overrride hashcode() when we override equals().
Consider a User class that has two fields: age and name.
public class User { String name; int age; public User(String name, int age) { this.name = name; this.age = age; } 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; } @Override public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof User)) return false; User user = (User) obj; return user.getAge() == this.getAge() && user.getName() == this.getName(); } @Override public int hashCode() { int result=17; result=31*result+age; result=31*result+(name!=null ? name.hashCode():0); return result; } }
Now write a test class to check the above class
public class UserTest { public static void main(String[] args) { User firstUser = new User("Joe", 35); User secondUser = new User("Joe", 35); HashSetusers = new HashSet (); users.add(firstUser); System.out.println(users.contains(secondUser)); System.out.println("firstUser.hashCode(): " + firstUser.hashCode() + " secondUser.hashCode():" + secondUser.hashCode()); } } // Output true firstUser.hashCode(): 64563636 secondUser.hashCode(): 64563636
But if we comment out the hascode override then it will produce the following result:
// Output flase firstUser.hashCode(): 64563636 secondUser.hashCode(): 72562565