Java中equals比较方法使用详解

 更新时间:2023年12月12日 09:57:17   作者:zues~  
这篇文章主要给大家介绍了关于Java中equals比较方法使用的相关资料,在Java中equals()方法是Object类的一个实例方法,用于比较两个对象是否相等,文中通过代码介绍的非常详细,需要的朋友可以参考下

1、equals方法的背景

在Java中,equals方法是Object类的一个方法,用于比较两个对象是否相等。

Java中有两种比较对象的方法:==运算符和equals方法。

==运算符用于比较两个对象的引用,如果它们指向的是同一个对象,则返回true;而equals方法用于比较两个对象的内容是否相等,当它们的内容相等时,则返回true。因此,equals方法可以用于比较两个值相同的字符串、整型等基本数据类型,或需要通过内容比较才能确定相等的自定义类对象等。

2、equals方法的使用

如何覆盖equals方法

在Java中,一个类如果想要正确地使用equals方法,一定要对该方法进行覆盖。覆盖equals方法的意思是,将equals方法从Object类中继承来的实现替换为自己的实现。如果不覆盖equals方法,则调用该方法时会使用继承的Object类的实现,这种默认实现无法提供正确的比较行为,因为它无法知道哪些属性或状态在两个对象中是必须相同的。

因此,覆盖equals方法的必要性在于提供一个自定义的比较行为,使得该方法可以正确地比较自定义类对象的内容是否相同。而覆盖equals方法的步骤如下:

1)确定对象相等的条件;

2)覆盖equals方法,实现对象相等的比较逻辑;

3)同时覆盖hashCode方法,确保相等的对象具有相等的hashCode值。

equals方法的实现

在重写equals方法时应该遵循以下的通用标准:

1)自反性:对于任何非null的引用值x,x.equals(x)应该返回true;

2)对称性:对于任何非null的引用值x和y,如果x.equals(y)返回true,则y.equals(x)也应该返回true;

3)传递性:对于任何非null的引用值x、y和z,如果x.equals(y)返回true,y.equals(z)也返回true,那么x.equals(z)也应该返回true;

4)一致性:对于任何非null的引用值x和y,如果用于equals比较的对象信息没有发生变化,那么无论进行多少次比较,都应该返回true或false;

5)非空性:对于任何非null的引用值x,x.equals(null)应该返回false。

下面是一个重写equals方法的例子,假设我们有一个自定义的EqualsDemo类:

public class EqualsDemo {
    private String name;
    private int age;
    private double salary;

    //构造函数和getter/setter方法

    // 重写equals方法
    public boolean equals(Object obj) {
        if (obj == this) {  // 如果是同一对象,返回true
            return true;
        }
        if (!(obj instanceof EqualsDemo)) {  // 如果obj不是Employee类对象,返回false
            return false;
        }
        EqualsDemo equalsDemo = (EqualsDemo)obj;  // 强制转换为Employee类对象
        return equalsDemo.name.equals(this.name) && equalsDemo.age == this.age && equalsDemo.salary == this.salary;
    }

    // 重写hashCode方法
    public int hashCode() {
        int result = 17;
        result = 31 * result + name.hashCode();
        result = 31 * result + age;
        long temp = Double.doubleToLongBits(salary);
        result = 31 * result + (int)(temp ^ (temp >>> 32));
        return result;
    }
}

在这个例子中,EqualsDemo类重写了equals方法,比较了该类的三个属性:name,age和salary。如果两个EqualsDemo对象的这三个属性都相等,则这两个EqualsDemo对象相等。同时,EqualsDemo类也重写了hashCode方法,根据该类的属性计算了hashCode值。

3、equals方法的使用注意事项

在使用equals方法时,需要遵循以下注意事项:

1)永远不要使用equals方法比较对象的类型。如果没有覆盖equals方法,则Object.equals(Object obj)只有在obj和本身引用同一个对象时才返回true;如果覆盖了equals方法,则equals(Object obj)所接收的参数类型必须与本身的类型相同或可以强制转换成本身类型。

2)永远不要使用equals方法比较字符串常量。在Java中,字符串常量是共享的,如果用equals方法比较两个字符串常量,可能会导致不正确的结果。

3)永远不要使用equals方法比较两个浮点型或双精度型的值。由于浮点数在计算机内部只能表示近似值,所以可能会导致不正确的结果。

4、equals方法的相关问题

1. equals方法与“==”有何区别?

在Java中,==运算符和equals方法都可以用于比较两个对象。它们之间的区别在于:

==运算符用于比较两个对象的引用,如果它们指向的是同一个对象,则返回true;

equals方法用于比较两个对象的内容是否相等,当它们的内容相等时,则返回true。

例如:

Integer a = new Integer(10);
Integer b = new Integer(10);
System.out.println(a == b); //false
System.out.println(a.equals(b)); //true

在这个例子中,a和b是两个不同的Integer对象,虽然它们的值相同,但是它们指向的是不同的对象,因此使用==运算符比较时返回false。但是,因为它们的值相同,使用equals方法比较时返回true。

2.equals方法与hashCode方法有何联系?

在Java中,每个对象都有一个默认的hashCode值,该值是一种与该对象有关的整数,并且具有以下特性:

1)如果两个对象相等,则它们的hashCode值一定相等;

2)如果两个对象的hashCode值相等,则它们不一定相等。

因此,在覆盖equals方法时,必须同时覆盖hashCode方法,以保证相等的对象具有相等的hashCode值。hashCode方法返回的值应该根据equals方法比较的对象信息计算得出,具体实现方式可以借鉴上面的例子。

3. equal方法的效率问题

在Java中,equals方法的执行效率可能会受到多种因素的影响,例如equals方法的实现逻辑、对象属性的数量和类型等。因此,在比较大规模的对象时,equals方法的效率可能会显著降低。

为了提高equals方法的执行效率,可以考虑以下几种方法:

1)先比较两个对象的hashCode值,如果它们的hashCode值不同,则这两个对象不相等,可以直接返回false;

2)将equals方法的比较顺序调整,将属性值变化频率低的属性放在前面比较;

3)使用缓存,将对象的hashCode值缓存起来,避免重复计算。

补充知识:重写equals方法练习

package object;
/*
判断两个person对象的内容是否相等
如果两个person对象的各个属性值都一样,则返回true,反之返回false
 */
public class EqualsExercise {
    public static void main(String[] args) {
        Person person1 = new Person("jack", 10, '男');
        Person person2 = new Person("jack", 10, '男');
        System.out.println(person1.equals(person2));   //输出结果是true
    }
}
 
class Person {
    private String name;
    private int age;
    private char gender;
 
    //重写Object的equals方法
    public boolean equals(Object obj) {
        //如果比较的两个对象是同一个对象,则直接返回true
        if (this == obj){   //this就代表调用equals方法的那个对象,obj就是方法里面的实参
            return true;
        }
        //类型判断
        if (obj instanceof Person){  //obj是Person,我们才比较
            //进行 向下转型(即obj转成Person); 因为我需要得到obj的各个属性,如果不转型,拿不到
            Person p = (Person) obj;
            return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;
        }
        //如果不是person,则直接返回false;总不能拿一个人跟一个狗比
        return false;
    }
 
 
    public Person(String name, int age, char gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public char getGender() {
        return gender;
    }
 
    public void setGender(char gender) {
        this.gender = gender;
    }
}

Tips:

instanceof的用法:result = object instanceof class

instanceof左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返false。

总结 

到此这篇关于Java中equals比较方法使用详解的文章就介绍到这了,更多相关Java equals比较方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中接收键盘输入的三种方法

    Java中接收键盘输入的三种方法

    这篇文章主要介绍了Java中接收键盘输入的三种方法,本文给出3个方法实现通过读取控制台的输入与用户实现交互,需要的朋友可以参考下
    2015-06-06
  • SpringBoot超详细讲解事务管理

    SpringBoot超详细讲解事务管理

    事务的作用就是为了保证用户的每一个操作都是可靠的,事务中的每一步操作都必须成功执行,只要有发生异常就 回退到事务开始未进行操作的状态。事务管理是Spring框架中最为常用的功能之一,我们在使用Spring Boot开发应用时,大部分情况下也都需要使用事务
    2022-08-08
  • SpringMvc配置静态资源访问路径的实现

    SpringMvc配置静态资源访问路径的实现

    本文主要介绍了SpringMvc配置静态资源访问路径的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Java中的HashMap集合深度解析

    Java中的HashMap集合深度解析

    这篇文章主要介绍了Java中的HashMap集合深度解析, HashMap可以说是Java中最常用的集合类框架之一,是Java语言中非常典型的数据结构,我们总会在不经意间用到它,很大程度上方便了我们日常开发,需要的朋友可以参考下
    2023-09-09
  • SpringBoot项目中Redis存储Session对象序列化处理

    SpringBoot项目中Redis存储Session对象序列化处理

    在 Spring Boot 项目中使用 Redis 存储 Session 时,对象的序列化和反序列化是关键步骤,下面我们就来讲讲如何在 Spring Boot 项目中处理 Redis 存储 Session 对象的序列化和反序列化吧
    2025-05-05
  • 解决SpringCloud Gateway配置自定义路由404的坑

    解决SpringCloud Gateway配置自定义路由404的坑

    这篇文章主要介绍了解决SpringCloud Gateway配置自定义路由404的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • springboot创建多module项目的实例

    springboot创建多module项目的实例

    这篇文章主要介绍了springboot创建多module项目的实例代码,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • SpringBoot2.0.3打印默认数据源为 HikariDataSource (null)问题

    SpringBoot2.0.3打印默认数据源为 HikariDataSource (null)问题

    这篇文章主要介绍了SpringBoot2.0.3打印默认数据源为 HikariDataSource (null)问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java for循环常见优化方法案例详解

    Java for循环常见优化方法案例详解

    这篇文章主要介绍了Java for循环常见优化方法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • 详解Java如何实现一个优秀的散列表

    详解Java如何实现一个优秀的散列表

    这篇文章主要通过简单的示例为大家详细介绍了在Java中如何实现一个优秀的散列表,文中的示例代码讲解详细,具有一定的参考价值,需要的可以了解一下
    2023-07-07

最新评论