hashcode相等的两个对象一定相等吗_hashCode为什么存在?

f93ac77c3cc2ce3d59b4ac7552b4d08d.png

这篇文章我想讲讲equals()和hashCode()的区别,这两个方法是Object类使用最频繁的两个方法,也是面试官考察基础时比较喜欢提问的两个方法。


首先,话不多说,一句话总结:

equals()用于判断两个对象是否相等,这是大家公认的。hashCode()被设计是用来使得哈希容器能高效的工作。
为什么这么说?在Java中,有一些哈希容器,比如Hashtable,HashMap等等。当我们调用这些容器的诸如get(Object obj)方法时,容器的内部肯定需要判断一下当前obj对象在容器中是否存在,然后再进行后续的操作。一般来说,判断是够存在,肯定是要将obj对象和容器中的每个元素一一进行比较,要使用equals()才是正确的。
但是如果哈希容器中的元素有很多的时候,使用equals()必然会很慢。这个时候我们想到一种替代方案就是hashCode():当我们调用哈希容器的get(Object obj)方法时,它会首先利用查看当前容器中是否存在有相同哈希值的对象,如果不存在,那么直接返回null;如果存在,再调用当前对象的equals()方法比较一下看哈希处的对象是否和要查找的对象相同;如果不相同,那么返回null。如果相同,则返回该哈希处的对象。

hashCode()返回一个int类型,两个int类型比较起来要快很多。所以我在文章开头说,hashCode()被设计用来使得哈希容器能高效的工作。也只有在哈希容器中,才使用hashCode()来比较对象是否相等,但要注意这种比较是一种弱的比较,还要利用equals()方法最终确认。我们把hashCode()相等看成是两个对象相等的必要非充分条件,把equals()相等看成是两个对象相等的充要条件

因此,在自定义一个类的时候,我们必须要同时重写equals()和hashCode(),并且必须保证:
其一:如果两个对象的equals()相等,那么他们的hashCode()必定相等。
其二:如果两个对象的hashCode()不相等,那么他们的equals()必定不等。

import java.util.HashMap;

public class Demo {
    public static void main(String[] args) throws Exception{
        Person person=new Person("xyz",22);
        HashMap<Person,Integer> hashMap=new HashMap<Person,Integer>();
        hashMap.put(person, 1);
        System.out.println(hashMap.get(new Person("xyz",22)));
    }
}
class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        if (age != person.age) return false;
        return name != null ? name.equals(person.name) : person.name == null;
    }

//    @Override
//    public int hashCode() {
//        int result = name != null ? name.hashCode() : 0;
//        result = 31 * result + age;
//        return result;
//    }
}

上面的代码注释掉hashCode()前后的运行结果不同,当注释掉hashCode()的时候,person和后来新建的Person虽然equals是同一对象,但HashMap容器内部在首先比较hashCode()的时候会认为他们是不同元素,所以返回的值不同。


牢记:

  1. 重写equals()方法时候一定要重写hashCode()方法。
  2. hashCode()相等是两个对象相等的必要非充分条件。
  3. equals()相等是两个对象相等的充要条件。

下次面试的时候,你能答对了吗!@E-臻。

介绍Java学习路线,关注下面 @E-臻 的Live:(近3000人收听)

学习Java,我建议这样做​www.zhihu.com
3de0fb917ef3d8894de19bb739cb3cb8.png

相当程序员,在大学怎么做?关注 @E-臻的Live

想当程序员,我建议大学生这样做​www.zhihu.com
3de0fb917ef3d8894de19bb739cb3cb8.png

想学云计算,我该怎么做?关注 @E-臻的Live

入门云计算:你该了解的那些事儿​www.zhihu.com
3de0fb917ef3d8894de19bb739cb3cb8.png

版权声明:本文为weixin_32440261原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。