Tuesday 15 February 2011

Implementing Hashcode

Implementing hashCode :
  • if a class overrides equals, it must override hashCode
  • when they are both overridden, equals and hashCode must use the same set of fields
  • if two objects are equal, then their hashCode values must be equal as well
  • if the object is immutable, then hashCode is a candidate for caching and lazy initialization
Misconception:

It is a popular misconception that hashCode provides a unique identifier for an object. It does not.

Cases of Inconsistency when not implementing equals() or hashCode() OR Why we need to override equals and hashCode() method

When implementing hashCode() but not equals()

public class MyString {



private String inputString;



public MyString(String string) {

inputString=string;

}



@Override

public int hashCode() {

return inputString.length();

}

}


 


Now lets see the result with tester class:


public static void main(String[] args) {



MyString obj1 = new MyString (“my-string”);

MyString Obj2 = new MyString (“my-string”);

if(obj1.hashCode() == obj2.hashCode()){

System.out.println(“HashCode are equal”);

}

if(obj1.equals(obj2)){

System.out.println(“Objects are equal”);

}else{

System.out.println(“Objects are not equal”);

}



}



Case when not implementing hashCode()


If the object does not implement hashcode() method and used as key then we will not get the object back as shown in below code.


class Person{
private String name;
private boolean gender;//false for female, true for male
//some getters and setters
//no equals and hashcode implemented in this class
}



Now using this class:


public class HashMapDemo {

public static void main(String[] args) {
Person person=new Person("ramesh",true);
Person person2 = new Person("ramesh",true);
Person person3 = new Person("suresh",true);
Person person4 = new Person("kavya",false);

HashMap<Person, String> map = new HashMap<Person, String>();
//Note that 2 duplicate object added to hashmap and no exception thrown...
map.put(person,"New person");
map.put(person2,"Duplicate person");
map.put(person3,"Another new person");
map.put(person4,"new Female person");

//
//Now retrieving the hashmap
Person rameshAgain=new Person("ramesh",true);
if(map.get(rameshAgain) == null)
System.out.println("Object not found");
else
System.out.println("Our object found in map");
}



Output:


Object not found



As you can see in above program :


  1. Duplicate objects are added in Hashmap as a key (Because we have not overided the hashcode and equals method)
  2. We are not able to get back object from map (Because hashcode is not implemented)

Some guidelines for implementing hashCode()


 


Implementing the hashCode() and equals()


Now implementing hashCode() and equals:


public class Person {

int id;

String name;

public boolean equals(Object obj){

if(this == obj) return true; // if both are referring to the same object
if ((obj == null) || (obj.getClass() != this.getClass())) {
return false;
}
Person rhs = (Person) obj;
return id == rhs.id &amp;&amp; (name == rhs.name ||
(name != null &amp;&amp; name.equals(rhs.name)) );

}

//both fields id &amp; name are used in equals(), so both fields must be used in

//hashCode() as well.

public int hashCode() {

int hash = 9;

hash = (31 * hash) + id;

hash = (31 * hash) + (null == name ? 0 : name.hashCode());

return hash;

}

}

No comments:

Post a Comment