为什么重写equals()后必须重写hashCode()?超详细解析!

本文详细解释了在Java中重写equals()方法后为何需要重写hashCode()。内容涵盖equals()的作用、与==的区别,hashCode()的作用及其与equals()的关系。强调在创建散列表时,相等对象必须有相同的hashCode(),否则会影响散列表的正确性。文中通过示例代码展示了不同时候覆盖这两个方法的影响。
摘要由CSDN通过智能技术生成

为什么重写equals()后必须重写hashCode()?超详细解析!

本文的内容主要解决下面几个问题:

1 equals() 的作用是什么

2 equals() 与 == 的区别是什么

3 hashCode() 的作用是什么

4 hashCode() 和 equals() 之间有什么联系?


第1部分 equals() 的作用

equals() 的作用是 用来判断两个对象是否相等

equals() 定义在JDK的Object.java中。通过判断两个对象的地址是否相等(即,是否是同一个对象)来区分它们是否相等。源码如下:

public boolean equals(Object obj) {
   
    return (this == obj);
}

既然Object.java中定义了equals()方法,这就意味着所有的Java类都实现了equals()方法,所有的类都可以通过equals()去比较两个对象是否相等。 但是,我们已经说过,使用默认的“equals()”方法,等价于“==”方法。因此,我们通常会重写equals()方法:若两个对象的内容相等,则equals()方法返回true;否则,返回fasle。

下面根据“类是否覆盖equals()方法”,将它分为2类。
(01) 若某个类没有覆盖equals()方法,当它的通过equals()比较两个对象时,实际上是比较两个对象是不是同一个对象。这时,等价于通过“==”去比较这两个对象。
(02) 我们可以覆盖类的equals()方法,来让equals()通过其它方式比较两个对象是否相等。通常的做法是:若两个对象的内容相等,则equals()方法返回true;否则,返回fasle。

下面,举例对上面的2种情况进行说明。

1. “没有覆盖equals()方法”的情况

代码如下 (EqualsTest1.java)

import java.util.*;
import java.lang.Comparable;

/**
 * @desc equals()的测试程序。
 *
 * @author skywang
 * @emai kuiwu-wang@163.com
 */
public class EqualsTest1{
   

    public static void main(String[] args) {
   
        // 新建2个相同内容的Person对象,
        // 再用equals比较它们是否相等
        Person p1 = new Person("eee", 100);
        Person p2 = new Person("eee", 100);
        System.out.printf("%s\n", p1.equals(p2));
    }

    /**
     * @desc Person类。
     */
    private static class Person {
   
        int age;
        String name;

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

        public String toString() {
   
            return name + " - " +age;
        }
    }
}

运行结果

false

结果分析

​ 我们通过 p1.equals(p2) 来“比较p1和p2是否相等时”。实际上,调用的Object.java的equals()方法,即调用的 (p1==p2) 。它是比较“p1和p2是否是同一个对象”。
​ 而由 p1 和 p2 的定义可知,它们虽然内容相同;但它们是两个不同的对象!因此,返回结果是false。

  1. "覆盖equals()方法"的情况

我们修改上面的EqualsTest1.java覆盖equals()方法

代码如下 (EqualsTest2.java)

 1 import java.util.*;
 2 import java.lang.Comparable;
 3 
 4 /**
 5  * @desc equals()的测试程序。
 6  *
 7  * @author skywang
 8  * @emai kuiwu-wang@163.com
 9  */
10 public class EqualsTest2{
   
11 
12     public static void main(String[] args) {
   
13         // 新建2个相同内容的Person对象,
14         // 再用equals比较它们是否相等
15         Person p1 = new Person("eee", 100);
16         Person p2 = new Person("eee", 100);
17         System.out.printf("%s\n", p1.equals(p2));
18     }
19 
20     /**
21      * @desc Person类。
22      */
23     private static class Person {
   
24         int age;
25         String name;
26 
27         public Person(String name, int age) {
   
28             this.name = name;
29             this.age = age;
30         }
31 
32         public String toString() {
   
33             return name + " - " +age;
34         }
35 
36         /** 
37          * @desc 覆盖equals方法 
38          */  
39         @Override
40         public boolean equals(Object obj){
     
41             if(obj == null){
     
42                 return false;  
43             }  
44               
45             //如果是同一个对象返回true,反之返回false  
46             if(this == obj){
     
47                 return true;  
48             }  
49               
50             //判断是否类型相同  
51             if(this.getClass() != obj.getClass())
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值