Wednesday 3 July 2013

equals() and hashCode() Contract

http://www.javatpoint.com/Hashtable-class-in-collection-framework

Java equals() and hashCode() Contract – Code Example

hashcode
The Java super class java.lang.Object has two very important methods defined:
1
2
public boolean equals(Object obj)
public int hashCode()
These methods prove very important when user classes objects are added to Maps. However, a good developer sometimes can not figure out how those should be overridden. In the following section, an example is given first, and then how equals() and hashCode contract works is explained.
1. A common mistake
Common mistake is shown in the example below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.HashMap;
public class Apple {
   private String color;
   public Apple(String color) {
      this.color = color;
   }
   public boolean equals(Object obj) {
      if (!(obj instanceof Apple))
         return false
      if (obj == this)
         return true;
      return this.color == ((Apple) obj).color;
   }
   public static void main(String[] args) {
      Apple a1 = new Apple("green");
      Apple a2 = new Apple("red");
      //hashMap stores apple type and its quantity
      HashMap<Apple, Integer> m = new HashMap<Apple, Integer>();
      m.put(a1, 10);
      m.put(a2, 20);
      System.out.println(m.get(new Apple("green")));
   }
}
In this example, a green apple object is stored successfully in a hashMap, but when the map is asked to retrieve this object, the apple object is not found. The program above prints null. However, we can be sure that the object is stored in the hashMap by inspection in the debugger(snapshot below).
2. Problem caused by hashCode()
The problem is caused by the un-overridden method “hashCode()”.
The contract between equals() and hasCode() is that: if two objects are equal, then they must have the same hash code, however the opposite is NOT true.
The idea behind a Map is to be able to find an object faster than a linear search. Using hashed keys to locate objects is a two-step process. Internally the Map stores objects as an array of arrays. The index for the first array is the hashcode() value of the key. This locates the second array which is searched linearly by using equals() to determine if the object is found.
hashCode() in default implementation in Object class returns distinct integers for distinct objects. Therefore, in the example above, same objects have different hashCode.
Hash Code is like a sequence of garages for storage, different stuff can be stored in different garages. It is more efficient if you organize stuff to different place instead of the same garage. So it’s good to equally distribute the hashCode value.
So the solution is to add hashCode method to class. Here I just use the color string’s length for demonstration.
1
2
3
public int hashCode(){
   return this.color.length();  
}

No comments:

Post a Comment