Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
Win a copy of Design for the Mind this week in the Design forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

equals() and hashCode()

 
shashank dwivedi
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why hashing based Collections are made such to force us override hashCode() whenever we override equals()??
 
James X Peterson
Whizlabs Java Support
Ranch Hand
Posts: 158
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi shashank dwived,


If you want to make your own immutable object , it will be wiser to override the equals() and hashCode() methods.Look the following examle

public class Emp
{
private int age ;

public Emp( int age )
{
super();
this.age = age;
}

}

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.

Now lets modify the class Emp by overriding methods hashcode() and equals.


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;
}
}

If you run compile and run the TestEmp class then the output will be

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

If you want to use your object as key not the value in the HashMap then you will override both methods


Regards,
James
 
shashank dwivedi
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
James Peterson wrote:Hi shashank dwived,


If you want to make your own immutable object , it will be wiser to override the equals() and hashCode() methods.Look the following examle

public class Emp
{
private int age ;

public Emp( int age )
{
super();
this.age = age;
}

}

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.

Now lets modify the class Emp by overriding methods hashcode() and equals.


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;
}
}

If you run compile and run the TestEmp class then the output will be

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

If you want to use your object as key not the value in the HashMap then you will override both methods


Regards,
James


Yes I know it works that way.But what actually i wanted to know is why HashSet unable to locate an object if hashCode() is not overridden even if equals() method is overridden?
Why can't equals method alone can do the job?
 
Matthew Brown
Bartender
Posts: 4566
8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
shashank dwivedi wrote:Yes I know it works that way.But what actually i wanted to know is why HashSet unable to locate an object if hashCode() is not overridden even if equals() method is overridden?
Why can't equals method alone can do the job?


You can quite write a set implementation that doesn't use hashCode(). But hashing algorithms are fast - even when you've got a very large set it allows you to locate objects very quickly. So having to override hashCode() is a small price to pay to be able to use these algorithms.
 
shashank dwivedi
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Matthew Brown wrote:
shashank dwivedi wrote:Yes I know it works that way.But what actually i wanted to know is why HashSet unable to locate an object if hashCode() is not overridden even if equals() method is overridden?
Why can't equals method alone can do the job?


You can quite write a set implementation that doesn't use hashCode(). But hashing algorithms are fast - even when you've got a very large set it allows you to locate objects very quickly. So having to override hashCode() is a small price to pay to be able to use these algorithms.

shashank dwivedi wrote:But it would not work as it will then allow to add me same object more than once and as per definition of Set duplicate values are not allowed to add.
 
Matthew Brown
Bartender
Posts: 4566
8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
shashank dwivedi wrote:But it would not work as it will then allow to add me same object more than once and as per definition of Set duplicate values are not allowed to add.

As long as you correctly implement hashCode() according to the contract then it won't let you add duplicates. The problems only arise if you override equals() without overriding hashCode().
 
abhisheksharma Mr
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is because it is a contract between hashCode() and euals ()

As per the java Api "Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes"

so if you wont you would get unexpected results

Thanks
Abhishek
 
Chintu Singh
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear Shashank,
Nobody is forcing a developer to override hashCode if he/she overrides equals.
If we want to retrieve anything out of our collection working on hashing algorithms, we should override both of the methods.

As per Object class's equals method, 2 references to objects are considered equal only if those are referring to the same object on the heap. And it is impossible to create exactly same objects (which point to the same object). And there is no benifit of keeping anything in the collections which uses hashing and forgot to retrieve the object out of it. So we read everywhere that we should override equals() and hashCode() both.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic