Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 9

HashCode and Equals method in Java

object – A pragmatic concept


Submitted by Debadatta Mishra on Fri, 08/08/2008 - 11:54.
Tags:
 compare your object with equal
 equals and hashcode concept in java

HashCode and Equals method in Java object – A pragmatic concept


By Debadatta Mishra
Introduction

Java.lang.Object has methods called hasCode() and equals(). These methods play a
significant role in the real time application. However its use is not always common to all
applications. In some case these methods are overridden to perform certain purpose. In
this article I will explain you some concept of these methods and why it becomes
necessary to override these methods.

hashCode()

As you know this method provides the hash code of an object. Basically the default
implementation of hashCode() provided by Object is derived by mapping the memory
address to an integer value. If look into the source of Object class , you will find the
following code for the hashCode.

public native int hashCode();

It indicates that hashCode is the native implementation which provides the memory
address to a certain extent. However it is possible to override the hashCode method in
your implementation class.

equals()

This particular method is used to make equal comparison between two objects. There are
two types of comparisons in Java. One is using “= =” operator and another is “equals()”. I
hope that you know the difference between this two. More specifically the “.equals()”
refers to equivalence relations. So in broad sense you say that two objects are equivalent
they satisfy the “equals()” condition. If you look into the source code of Object class you
will find the following code for the equals() method.

public boolean equals(Object obj)


{
return (this == obj);
}

Now I will explain you when to override the equals() and hashCode() methods and why it
is necessary to override these methods. In this regard there is a rule of thumb that if you
are going to override the one of the methods( ie equals() and hashCode() ) , you have to
override the both otherwise it is a violation of contract made for equals() and hashCode().
Please refer to the Sun’s java docs for the method’s contract. I provide some test case
scenario where you will find the significance of these methods.

Case-1:

You can override the hashCode method in your own way. Please refer to the following
example.

package com.ddlab.core;

/**
* @author Debadatta Mishra(PIKU)
*
*/
public class Emp
{
private int age ;

public Emp( int age )


{
super();
this.age = age;
}

public int hashCode()


{
return age;
}
}

In the above example class “Emp” the variable age is the significant factor. Here the
hashCode value will return the age of the person. Now let us consider the following test
harness class.
package com.ddlab.core;

/**
* @author Debadatta Mishra(PIKU)
*
*/
public class TestEmp
{
public static void main(String[] args)
{
Emp emp1 = new Emp(23);
System.out.println("emp1.hashCode()--->>>"+emp1.hashCode());
}
}

If you run the above program, the output will be the age what you have given i.e. 23.
Now question arises whether there is any way we can get the original hashCode(). We can
say that if we do not override the hashCode() method what could have been the hashCode
of this object. However please do not feel depressed, Java provide another approach even
if you have overridden the hashCode() method , still you can get the original hashCode of
a particular class. Now run the following test harness program.

package com.ddlab.core;

package com.ddlab.core;

/**
* @author Debadatta Mishra(PIKU)
*
*/
public class TestEmp
{
public static void main(String[] args)
{
Emp emp1 = new Emp(23);
System.out.println("Overridden hashCode()--->>>"+emp1.hashCode());
int originalHashCode = System.identityHashCode(emp1);
System.out.println("Original hashCode of Emp---->>>"+originalHashCode);
}
}

Here the output will be like this


Overridden hashCode()--->>>23
Original hashCode of Emp---->>>8567361

As you know the above number is arbitrary, it depends upon your system.
So then why it is necessary to override this method. There is one reason that if want to
compare two objects based upon the equals() method. Although in a very simple class
like “Emp”, you can achieve without overriding hashCode() method. But if you do this ,
you are going to violate the contract for the methods hashCode() and hashCode() of the
object class. The similar case is for the method equals(). So funcational point is that if
want to compare two objects based upon the equals() method you have to override both
hashCode() and equals() methods. Please have look into the Emp class with the
overridden methods and the related test harness class.

package com.ddlab.core;

/**
* @author Debadatta Mishra(PIKU)
*
*/
public class Emp
{
private int age ;
public Emp( int age )
{
super();
this.age = age;
}

public int hashCode()


{
return age;
}

public boolean equals( Object obj )


{
boolean flag = false;
Emp emp = ( Emp )obj;
if( emp.age == age )
flag = true;
return flag;
}
}

The related test harness class is given below.


package com.ddlab.core;

/**
* @author Debadatta Mishra(PIKU)
*
*/
public class TestEmp
{
public static void main(String[] args)
{
Emp emp1 = new Emp(23);
Emp emp2 = new Emp(23);
System.out.println("emp1.equals(emp2)--->>>"+emp1.equals(emp2));
}
}

Case- 2

Think of a test scenario where you want to store your objects in a HasSet and you want to
find a particular object. First let us see if we do not override the methods and we want to
store the objects in the HashSet. Let us analyse the impact of it from the following code.

package com.ddlab.core;

/**
* @author Debadatta Mishra(PIKU)
*
*/
public class Emp
{
private int age ;
public Emp( int age )
{
super();
this.age = age;
}

In the above code it is a normal class. Now let us see the test harness class.
package com.ddlab.core;

import java.util.HashSet;

/**
* @author Debadatta Mishra(PIKU)
*
*/
public class TestEmp
{
public static void main(String[] args)
{
Emp emp1 = new Emp(23);
Emp emp2 = new Emp(24);
Emp emp3 = new Emp(25);
Emp emp4 = new Emp(26);
Emp emp5 = new Emp(27);
HashSet<Emp> hs = new HashSet<Emp>();
hs.add(emp1);
hs.add(emp2);
hs.add(emp3);
hs.add(emp4);
hs.add(emp5);

System.out.println("HashSet Size--->>>"+hs.size());
System.out.println("hs.contains( new Emp(25))--->>>"+hs.contains(new
Emp(25)));
System.out.println("hs.remove( new Emp(24)--->>>"+hs.remove( new
Emp(24));
System.out.println("Now HashSet Size--->>>"+hs.size());
}
}

If you run the above program, the will output will be like the following.

HashSet Size--->>>5
hs.contains( new Emp(25))--->>>false
hs.remove( new Emp(24)--->>>false
Now HashSet Size--->>>5

It means that you can not find the object. However it is not the case for Integer object.
You can put object of type Integer in a HashSet and you can try and you can see the
effect. Now let us modify the “Emp” class so that we will get over the problems what we
faced in the above test harness class.
package com.ddlab.core;

/**
* @author Debadatta Mishra(PIKU)
*
*/
public class Emp
{
private int age ;

public Emp( int age )


{
super();
this.age = age;
}

public int hashCode()


{
return age;
}

public boolean equals( Object obj )


{
boolean flag = false;
Emp emp = ( Emp )obj;
if( emp.age == age )
flag = true;
return flag;
}
}

Here in the above class, we have overridden the hashCode() and equals() methods. Now
if you run the same test harness class, you will get the desired output like the following.

HashSet Size--->>>5
hs.contains( new Emp(25))--->>>true
hs.remove( new Emp(24))--->>>true
Now HashSet Size--->>>4

Case – 3

In this case you want to use your object as key not the value in the HashMap. So you
have to override both the methods hashCode() and equals(). However it is left to the
reader to create the object and test the feature in a Map.

Case-4

If want to make your own immutable object , it will be wiser to override the equals() and
hashCode() methods.
To test the above programs, please create the appropriate package as mentioned in the
program. You can also create your own package and modify the package name in the
above programs. You can all the code in your favorable java editor.

Conclusion
I hope that you will enjoy my article. If you find any problems or errors, please feel free
to send me a mail in the address debadattamishra@aol.com . This article is only meant
for those who are new to java development. This article does not bear any commercial
significance. Please provide me the feedback about this article.

Sorting HashMap with different Scenarios

This code snippet will explain the hashmap functionality and its sorting feature.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

public class SortingHash {

static Map myMap = new HashMap();


static HashMap map = new LinkedHashMap();

/**
* setting values for hashmap
*/
static void sethash() {
myMap.put("E", 5);
myMap.put("B", 2);
myMap.put("A", 1);
myMap.put("D", 4);
myMap.put("C", 3);

}
public static void main(String a[]) {
sethash();
sortKey();
sortValue();
}

/**
* Sorting hashmap with key
*/
static void sortKey() {
SortedSet<String> sortedset = new
TreeSet<String>(myMap.keySet());

Iterator<String> it = sortedset.iterator();

while (it.hasNext()) {
System.out.println(it.next());
}
}

/**
* Sorting hashmap with value
*/
static void sortValue() {
List yourMapKeys = new ArrayList(myMap.keySet());
List yourMapValues = new ArrayList(myMap.values());
TreeSet sortedSet = new TreeSet(yourMapValues);
Object[] sortedArray = sortedSet.toArray();
int size = sortedArray.length;
System.out.println("---------------");
for (int i = 0; i < size; i++) {
System.out.println((Integer) sortedArray[i]);
}
for (int i = 0; i < size; i++) {

map.put(yourMapKeys.get(yourMapValues.indexOf(sortedArray[i
])),
sortedArray[i]);
}
Set ref = map.keySet();
Iterator it = ref.iterator();
System.out.println("---------------");
while (it.hasNext()) {
System.out.println((String) it.next());
}
}

If two different objects have same


hashcode, how HashMap will retrieve
these two objects?

You might also like