Wednesday, August 12, 2015

[Java] Java equals() and hashCode() 08/12

Problem: Java: Why does my compiler warn me about overriding equals() in my class without overriding hashCode()?

 1. Common mistake
import java.util.HashMap;

public class NameTag
{
    private String name;
    public NameTag(String name)
    {
        this.name = name;
    }
    
    public boolean equals(Object obj)
    {
        if ( !(obj instanceof NameTag) )
        {
            return false;
        }
        if ( obj == this ) 
        {
            return true;
        }
        return this.name.equals( ((NameTag) obj).name  ); 
    }
    public static void main (String[] args)
    {
        NameTag n1 = new NameTag("Bob");
        NameTag n2 = new NameTag("Tom");
        
        // store name and its quantity
        HashMap map = new HashMap();
        map.put(n1, 2);
        map.put(n2, 3);
        System.out.println( map.get(new NameTag("Tom")) );
    }
}

Compile and Executed Result:
null


2. Root Cause

The problem is "n2" and "new NameTag("Tom")" has different hashed keys, that's why Hashmap fails in the first step of search. Explained more in below.

Using map.get(key) to find an object is two-step process and map store objects as two array.

First, it will use hashed keys to locate the objects and thus we search the first array which is the hashcode() value of the key.

Second, this locates the second array which is search linearly by using equals() to determine if the object is found.

So we failed in the first step and don't even get to the second step and call equals() method.

3. Solution

Add hashCode() into the class NameTag with equals()
import java.util.HashMap;

public class NameTag
{
.
.
.
.
.
   public int hashCode()
   {
       return this.name.length();
   }
}
Summary:
1. If two objects are equal, they mush have the same hashcode.
2. If two objects are not equal, they don't have to be have the same hashcode. In other words, Two objects have the same hashcode doesn't mean that they have the are equal.

4. References
http://www.programcreek.com/2011/07/java-equals-and-hashcode-contract http://tutorials.jenkov.com/java-collections/hashcode-equals.html

No comments:

Post a Comment