关于hashCode和equals重写

规则

  1. 只要重写equals,就必须重写hashCode。

  2. 用Set存储对象或者用对象作为Map的键时,必须重写hashCode。也就是说,当需要用对象的哈希值来判断对象是否相等时必须重写hashCode。

    说明:String重写了hashCode和equals方法,所以我们可以非常愉快地使用String对象作为key来使用。

介绍

  1. Equals的作用是用来判断两个对象是否相等。
  2. hashCode 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数,这个哈希码的作用是确定该对象在哈希表中的索引关系。

关系(我们以“类的用途”来将“hashCode()和equals()的关系”分两种情况来说明)

  1. 不会创建“类对应的散列表”

    不会创建类对应的散列表是说:我们不会在HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中,用到该类。例如,不会创建该类的HashSet集合,不会以该类作为Map的键。在这种情况下,hashCode和 equals是没有关系的。而hashCode() 则根本没有任何作用。

    equals() 用来比较该类的两个对象是否相等,必要时还是需要重写。以下这种情况按照正常业务应该返回true,但是实际结果却是false。

    public static void main(String[] args) {
        Student student1 = new Student();
        student1.setName("张三");
        student1.setAge(1);
    
        Student student2 = new Student();
        student.setName("张三");
        student.setAge(1);
    
        System.out.println(student1.equals(student2));
    }
    

    重写equals我们就可以根据我们实际的情况来判断是否相等。

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }
    

    这种情况下,hashCode没有实际意义

  2. 会创建类对应的散列表

    创建类对应的散列表是说:我们会在HashSet,Hashtable,HashMap等等这些本质是散列表的数据结构中,用到该类。在这种情况下,该类的“hashCode()和equals()”是有关系的:

    1. 如果两个对象相等,那么hashCode返回的值一定相等,通过equals比较两个对象也相等。
    2. 如果两个对象hashCode()相等,它们并不一定相等。因为在散列表中,hashCode相等,即两个键值对的哈希值相等。然而哈希值相等,不一定能得出键值对相等。补充说一句:“两个不同的键值对,哈希值相等”,这就是哈希冲突。

总结

以程序角度看图1中student1和student2必然是两个不同的对象,new对象的时候JVM分配的不通的内存。但是以业务和面向对象来看,student1和student2的所有属性都相同,我们必须把他们当成同一个对象来处理。需要比较的时候我们则需要重写equals来具体比较对象的属性值,用Set去重时我们也得重写hashCode来给这种相对的对象返回相等的哈希值。如果没有以上需求则不用重写hashCode和equals,这两者也没有关系。这是自己对重hashCode和equals的理解,因为自己技术菜理解比较片面。专业解释还请看 说说hashCode() 和 equals() 之间的关系

类对应的散列表

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

posted @ 2021-09-30 15:49  橘子丶李  阅读(178)  评论(0编辑  收藏  举报