java hashcode and equals method example

hashcode and equals method in Java:-

hashcode and equals in Java are the two basic fundamental methods present in the Object class. Most collection classes use hashcode()equals() method to check object equality.Java.lang.Object has methods called hasCode() and equals(). These methods play a crucial role in an application.

How java hashcode Method Works :-

java.lang.object has hashCode() method , which returns hashcode of an object . If we look at source code of the object class we can see the code as following

 public native int hashCode();

This is  native method, because it has to interact with the machine. Here machine dependent code is written in the C language, which is not coming with the source package or in rt.jar of the lib location of the Java Runtime Environment (JRE).The hashCode method returns an integer value dependent on the internal representation of a pointer to an object on the heap.

This method  converts object internal address to an integer , as internal address is not available via Java SDK hence it is native. Lets discuss what are equals and hascode methods.

How Java equals Method Works :-

We all know Java equals method is used to compare objects , object comparison is basic necessity in complex scenarios .

Technically there are two basic way to compare objects

  1. Using Default Implementation
  2. Using Custom logic .

This method does the object comparison in java between two different objects .Let’s look at objects code for equals method

public boolean equals(Object obj) {
       return (this == obj);
    }

Now , above code  returns true if and only if both variables refer to the same object, if their references are one and the same .

Why Do we Need to override hashCode and equals method:-

It is generally necessary to override the hashCode method whenever equals method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.Failure to do so will result in a violation of the general contract for hashcode, and improper functioning of the classes with collections such as  HashMap, HashSet, and Hashtable. Let’d Find out what will happen if we override any one .

1.Override the Only HashCode:-

Employee.java:- 

We are overriding the hashcode method only.

public class Employee {

	String name;
	int id;
	
	
	public Employee(String name, int id) {
		super();
		this.name = name;
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	
	
	
	
}

Test.java:-

import java.util.HashMap;
import java.util.Map;


public class MapImpl {

	public static void main(String[] args) {
	
		Map<Employee, String> map=new HashMap<Employee, String>();
		
		Employee e=new Employee("Frugalis", 1);
		Employee e2=new Employee("Frugalis", 1);
		
		System.out.println("Hsashcode Of 1st "+e.hashCode());
		System.out.println("HashCode of 2nd "+e2.hashCode());
		
		map.put(e, "Frugalis");
		map.put(e2, "Minds");
		
	
		  for(Map.Entry m:map.entrySet()){
			 
			   System.out.println(m.getValue());
			  }
		
		
	}

}

 Output:-

Hashcode Of 1st -1013392397
HashCode of 2nd -1013392397
Frugalis
Minds

Explanation:-

Once we are declaring two employee objects with same value like below

Employee e=new Employee("Frugalis", 1);
Employee e2=new Employee("Frugalis", 1);

If we override only hashcode and try to put it inside map by calling map.put(e, "Frugalis") , it takes e calculates its hashcode and allocates a particular memory location or a bucket. Now again if  we try to put in map by calling map.put(e2, "Frugalis") , logically if we think in a business scenario perspective or hashmap perspective , it should replace first with second as both are same and equal . But it inserts both of them in a map .Why So ?

So the problem here is equal was not overriden , so once map hashes second object e2 and iterates through bucket to check for any object that is equal to e2,  it calls equals method . As we do not override equals method here , it calls object class equals method  and returns false , as object class default implementation of equals checks the reference of two objects and we have  both references are different in this case .

2. Overriding Only equals method:-

Employee.java:- 

We are overriding the equals method only.

public class Employee {
	String name;
	int id;
	
	public Employee(String name, int id) {
		super();
		this.name = name;
		this.id = id;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}



	@Override
	public String toString() {
		return "Employee [name=" + name + ", id=" + id + "]";
	}

	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Employee other = (Employee) obj;
		if (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	

}

Test.java:-

import java.util.HashMap;
import java.util.Map;

public class Test{

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Map<Employee, String> map=new HashMap<Employee, String>();
		
		Employee e=new Employee("Frugalis", 1);
		Employee e2=new Employee("Frugalis", 1);
		
		System.out.println("Hsashcode Of 1st "+e.hashCode());
		System.out.println("HashCode of 2nd "+e2.hashCode());

		map.put(e, "Frugalis");
		map.put(e2, "Minds");
		
	
		  for(Map.Entry m:map.entrySet()){
			 
			   System.out.println(m.getKey().toString());
			  }
	}

}

Output:-

Hsashcode Of 1st 705927765
HashCode of 2nd 366712642
Employee [name=Frugalis, id=1]
Employee [name=Frugalis, id=1]

Explanation:-

If only equals is overriden, then when you call map.put(e1,"Frugalis") e1 will hash to some bucket and when you call map.put(e2,"minds") it will hash to some other bucket (as they have a different hashCode returned).

So, although they are equal, as they don’t hash to the same bucket, the map can’t realize it and both of them stay in the map , which is again not relevant as per a real time business logic.

Conclusion :-

As you can see in both scenarios implementing any one of hashcode and equals doesnt gives you a correct result .By defining equals() and hashCode() consistently, you can improve the usability of your classes as keys in hash-based collections .

So when you need to use your object in the hashing based collection, must override both equals() and hashCode()

I hope i have made it fully clear and if you guys have any question , please comment and Subscribe .

Suggest me the Topics You Want to know More  In Comments Below  .