我在覆盖 equals 方法时遇到了一些问题。这是我的代码如下:
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;
}
}
它生成的输出为:
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
我已经覆盖了始终返回 false 的等于方法,并且哈希代码方法始终返回相同的值。因此,根据这一点,每个对象都将落在同一个存储桶上。但我的问题是我无法理解当 equals 方法总是返回 false 时,那么为什么它能够提供与键匹配的正确输出。
请帮忙。提前谢谢。
如果您查看HashMap
实现,您会发现此方法执行实际查找:
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;
}
首先通过引用比较密钥(见//!
),然后通过相等性进行比较。因此,尽管您的equals
实现错误,但它仍返回正确的值。
hashmap 首先检查引用相等性,如果通过,它将跳过 .equals 调用。这是一个优化并且有效,因为 equals 的合约指定如果 a == b 则 a.equals(b)。
试试这个 -
员工emp2x=新员工(); emp2x.setName("emp2");
System.out.println("map element are "+map.get(emp2x));