Java 覆盖hashmap中的equals问题
我在重写equals方法时遇到了一些问题。以下是我的代码:Java 覆盖hashmap中的equals问题,java,Java,我在重写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(); em
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;
}
}
我已经重写了总是返回false的equals方法和总是返回相同值的hashcode方法。因此,根据这个原理,每个物体都会落在同一个桶上。但我的问题是,我无法理解当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;
}
final节点getNode(int散列,对象键){
节点[]选项卡;节点第一,e;int n;K;
如果((tab=table)!=null&(n=tab.length)>0&&
(first=tab[(n-1)&散列]!=null){
如果(first.hash==hash&&//始终检查第一个节点
((k=first.key)==key | |(key!=null&&key.equals(k)))/!
先返回;
if((e=first.next)!=null){
if(树节点的第一个实例)
return((TreeNode)first).getTreeNode(hash,key);
做{
如果(e.hash==hash&&
((k=e.key)==key | |(key!=null&&key.equals(k)))/!
返回e;
}而((e=e.next)!=null);
}
}
返回null;
}
首先通过引用比较键(请参见
/!
),然后通过相等进行比较。因此,它返回正确的值,尽管您的实现有缺陷,但它等于实现 如果查看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;
}
final节点getNode(int散列,对象键){
节点[]选项卡;节点第一,e;int n;K;
如果((tab=table)!=null&(n=tab.length)>0&&
(first=tab[(n-1)&散列]!=null){
如果(first.hash==hash&&//始终检查第一个节点
((k=first.key)==key | |(key!=null&&key.equals(k)))/!
先返回;
if((e=first.next)!=null){
if(树节点的第一个实例)
return((TreeNode)first).getTreeNode(hash,key);
做{
如果(e.hash==hash&&
((k=e.key)==key | |(key!=null&&key.equals(k)))/!
返回e;
}而((e=e.next)!=null);
}
}
返回null;
}
首先通过引用比较键(请参见/!
),然后通过相等进行比较。因此,它返回正确的值,尽管您的实现有缺陷,但它等于实现 试试这个-
员工emp2x=新员工();
emp2x.集合名(“emp2”)
System.out.println(“map元素是”+map.get(emp2x)) 试试这个-
员工emp2x=新员工();
emp2x.集合名(“emp2”)
System.out.println(“map元素是”+map.get(emp2x)) hashmap首先检查引用相等,如果通过,则跳过.equals调用。这是一种优化,因为equals契约指定如果a==b,那么a.equals(b)。hashmap首先检查引用的相等性,如果通过,则跳过.equals调用。这是一个优化,因为equals契约指定如果a==b,那么a.equals(b)。我没有检查实现,但可能它在a==b
时使用了一个快捷方式,并且没有调用a.equals(b)
在本例中。我没有检查实现,但可能它在a==b
时使用了快捷方式,在本例中不调用a.equals(b)
。非常感谢。这是我认识的新事物。真的谢谢……非常感谢。这是我认识的新事物。真的谢谢。。