Reputation: 79
I am facing some problem while overriding the equals method. Here is my code as below:
import java.util.HashMap;
import java.util.Map;
public class HashCodeTest {
public static void main(String[] args) {
Employee emp1=new Employee();
emp1.setName("emp1");
Employee emp2=new Employee();
emp2.setName("emp2");
Employee emp3=new Employee();
emp3.setName("emp3");
Map map=new HashMap<Employee,String>();
System.out.println("put a");
map.put(emp1, "a");
System.out.println("put b");
map.put(emp2, "b");
System.out.println("put c");
map.put(emp3, "c");
System.out.println();
System.out.println("map element are "+map);
System.out.println("get 3rd obj");
System.out.println("map element are "+map.get(emp3));
System.out.println();
System.out.println("get 2nd obj");
System.out.println("map element are "+map.get(emp2));
}
}
class Employee
{
.
.
getters and setters
@Override
public int hashCode()
{
System.out.println("hashcode called");
return 12;
}
@Override
public boolean equals(Object str)
{
System.out.println("equal called");
return false;
}
}
It produces the output as:
put a
hashcode called
put b
hashcode called
equal called
put c
hashcode called
equal called
equal called
map element are {name emp3=c, name emp2=b, name emp1=a}
get 3rd obj
hashcode called
map element are c
get 2nd obj
hashcode called
equal called
map element are b
I have overridden equals method that always return false and hashcode method always return the same value. So, as per this each object will fall on same bucket. But my problem is that i am not able to understand when equals method always return false then why it is able to give the correct output that matches the key.
Please Help. Thanks in advance.
Upvotes: 1
Views: 85
Reputation: 7016
The hashmap checks reference equality first, and if that passes, it skips the .equals call. This is an optimization and works because the contract of equals specifies that if a == b then a.equals(b).
Upvotes: 1
Reputation: 21
Try this -
Employee emp2x=new Employee(); emp2x.setName("emp2");
System.out.println("map element are "+map.get(emp2x));
Upvotes: 0
Reputation: 32980
If you look into the HashMap
implementation you find this method which does the actual lookup:
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k)))) // !
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) // !
return e;
} while ((e = e.next) != null);
}
}
return null;
}
The key is compared by reference first (see //!
) and then by equality. So it returns the right value despite your faulty equals
implementation.
Upvotes: 4