简体   繁体   English

哈希图中的覆盖等于问题

[英]overriding equals issue in hashmap

I am facing some problem while overriding the equals method. 我在覆盖equals方法时遇到了一些问题。 Here is my code as below: 这是我的代码如下:

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;
}
}

It produces the output as: 它产生的输出为:

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

I have overridden equals method that always return false and hashcode method always return the same value. 我已经重写了equals方法,该方法始终返回false,而hashcode方法始终返回相同的值。 So, as per this each object will fall on same bucket. 因此,按照此方法,每个对象都将落在同一存储桶上。 But my problem is that i am not able to understand when equals method always return false then why it is able to give the correct output that matches the key. 但是我的问题是我无法理解equals方法何时总是返回false,为什么它能够给出与键匹配的正确输出。

Please Help. 请帮忙。 Thanks in advance. 提前致谢。

If you look into the HashMap implementation you find this method which does the actual lookup: 如果查看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;
}

The key is compared by reference first (see //! ) and then by equality. 首先通过引用比较该键(请参阅//! ),然后通过相等比较。 So it returns the right value despite your faulty equals implementation. 因此,即使您的equals实现错误,它仍会返回正确的值。

The hashmap checks reference equality first, and if that passes, it skips the .equals call. 哈希图首先检查引用相等性,如果通过,则跳过.equals调用。 This is an optimization and works because the contract of equals specifies that if a == b then a.equals(b). 这是一个优化并且有效,因为等号合约规定如果a == b,则a.equals(b)。

Try this - 尝试这个 -

Employee emp2x=new Employee(); 雇员emp2x = new Employee(); emp2x.setName("emp2"); emp2x.setName(“ emp2”);

System.out.println("map element are "+map.get(emp2x)); System.out.println(“ map元素是” + map.get(emp2x));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM