Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Correctly override equals and hashcode

 
Amieya Prabhaker
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you let me know how to correctly override equals method so that the set distinguishes and does not add "meaningfully equal" objects.

The following code gives output: (I was expecting it to be Total: 3 with non-duplicates)
Adding: Hans
Adding: Lotte
Adding: Jane
Adding: Hans
Adding: Jane
Total: 5
=========================================================================
import java.util.*;
public class Group extends HashSet<Person> {
public static void main(String[] args) {
Group g = new Group();
g.add(new Person("Hans"));
g.add(new Person("Lotte"));
g.add(new Person("Jane"));
g.add(new Person("Hans"));
g.add(new Person("Jane"));
System.out.println("Total: " + g.size());
}
public boolean add(Person o) {
System.out.println("Adding: " + o);
return super.add(o);
}
}
class Person {
public String name;
public Person(String name) { this.name = name; }
public String toString() { return name; }
public boolean equals(Person p) {
return (this.name).equals(p.name);
}
public int hascode(Person p){
return p.name.length();
}
}
 
Amieya Prabhaker
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just realized the typo in hashCode, even changing it to hashCode gives the same output of Total: 5.
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator



u r not overriding hashCode method in ur class. Even if its hashCode() instead of hasCode().

use this signature for hashCode()...



regards
[ June 08, 2006: Message edited by: Naseem Khan ]
 
Amieya Prabhaker
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for pointing out the method signature for hashCode().
The compilation still gives the output as Total: 5

If I understand as HashSet correctly, it is a Set so cannot take duplicates.
How do I make 2 persons "equal" so that the HashSet sees them as duplicates.
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I forgot 2 see the signature of equals() method

U hav overloaded equals(Person) method in Person class.

It shud be like this....



for hashCode() signature is....




regards
 
Amieya Prabhaker
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Gotcha!

Thanks.
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am afraid that the suggested implementations of equals and hashCode presented until now are not the best ones I have ever seen. Actually they are pretty bad, as far as I understand.

First, the contract of equals does not let space to throw any exception. In the implementation suggested in the previous post you could easily provoke a NullPointerException or a ClassCastException.

A better implementation could be:



In this case, it the parameter is null, it will not survive the instanceof operator, if the parameter is actually the same object, it will not go beyond the o==this, and finally, if the value of name is null, it will not cause a NullPointerException.

Regarding hashCode, the implementation in the previous post suggests to return the length of the name field member. However, the idea behind hashCode is that every object can have a unique integer identifier. Although this is not a easy task, returning the length of a String for hashCode is not exactly a smart idea.

Hashcodes are used by HashMap, HashSet and Hashtable, and in this case all the Strings with the same length will return the same hashCode provoking collisions in these collections and, even worse, performance problems. Collisions in Hash tables transform them into simple linked lists.

A better idea about your hashCode method could be:



Once again, take nullability into account, and for objects you can recycle the default hashCode implementation.

I indeed recommend you to give a look to Joshua Bloch's book: Effective Java.

It has a couple of chapters about how to implement equals and hashCode correctly, among many other useful suggestions. It is a must-read for Java developers.

Good luck, comrade!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic