我在覆盖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方法,而hashcode方法总是返回相同的值。因此,根据这一点,每个对象将落在同一个桶上。但我的问题是,我无法理解何时equals方法总是返回false,那么为什么它能够提供与键匹配的正确输出。
请帮助。提前谢谢。
答案 0 :(得分:4)
如果您查看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
,它仍会返回正确的值。
答案 1 :(得分:1)
hashmap首先检查引用相等性,如果超过,则跳过.equals调用。这是一种优化并且有效,因为等于的合约指定如果a == b则a.equals(b)。
答案 2 :(得分:0)
试试这个 -
员工emp2x =新员工(); emp2x.setName(&#34; EMP2&#34);
System.out.println(&#34;地图元素是&#34; + map.get(emp2x));