覆盖等于hashmap中的问题

时间:2016-02-01 12:08:51

标签: 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();
    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,那么为什么它能够提供与键匹配的正确输出。

请帮助。提前谢谢。

3 个答案:

答案 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));