在哈希图中覆盖等于问题



我在覆盖 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));

最新更新