解析java中的equals方法

本文详细介绍了Java中equals方法的含义、作用以及如何重写。通过对比两种重写策略,展示了如何确保对象内容相等时返回true。文中提供了IDEA和Eclipse中自动生成equals方法的步骤,并强调了在自定义类中重写equals方法的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解析java中的equals方法

1 含义

在java.lang.Object下的一个访问权限为public 返回值为boolean的方法

若子类无重写,默认比较的就是两个对象(引用)的内存地址值是否相等,相等就返回true,不相等就返回false

2 作用

一般都重写Object类中的equals方法用于信息(需要展示的)的比较

当两个对象里面的内容相同时,就认为这两个对象是相等,与其地址值无关

举例说明:如比较两本书,只需要比较书的书名、类型、作者、价格、ISBN号,当所有的属性都相等时,我们就可以认为它是同一本书,和这个书的引用是否相等是没有半毛钱关系的

3 如何用

3.1 手动书写

3.1.1 书写思路
前提

两个思路都会执行下面的判断

a 当两个对象的引用指向的是同一个地址时,返回的是true;

b 当传进来的引用为null时,返回false

c 当传进来的引用和调用者不是同一个类的实例化对象时,那么返回false

(因为向下转型,要求类型必须保持一致,而且类型不一致也没有比较的必要)

思路一 把不相等的内容在前面返回false,到最后的时候才返回true
核心

依次拿属性进行比较

引用数据类型比较时

当传进来的引用中的引用数据类型的属性为null时,且调用者对应的字符串属性不为null时,那么返回false,否则,调用equals方法比较,若结果为false,则也返回false

注意:这个引用数据类型必须重写equals方法,不然默认调用的就是Object里面的方法

Object里面的equals方法比较的是两个引用的内存地址是否相等

基本数据类型比较时

若传进来的引用的基本数据类型的变量与调用者相应的基本数据类型的变量的值不相等时,则返回false

比较完最后一个属性后,依然没有返回false

执行到最后,那就返回true

思路二 直接return返回两个对象所有属性比较的结果(Objects工具类)
核心

一次性比较完所有内容,然后把比较的结果作为返回值,返回回去

比较过程

return 比较语句(用**&&符号**连接起来)

当比较引用数据类型的属性时,使用Objects.equals(引用1,引用2)进行比较,当比较基本数据类型时,直接用==比较即可,

在这个比较语句当中只要有一个为false,那么最终的返回值结果因为false,否则返回true

因为&&符号是短路与,只要有一个为false,后面的都不会进行比较了

3.1.2 示例核心代码
思路一
@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Dog other = (Dog) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (type == null) {
			if (other.type != null)
				return false;
		} else if (!type.equals(other.type))
			return false;
		return true;
	}
思路二
  @Override
    public boolean equals(Object o) {
        //如果条件判断里面的内容只有一行,则可以省略{}不写,但是写代码时不建议这么干
        //因为这样的话逻辑很有可能把自己给绕晕的
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Dog dog = (Dog) o;
        return age == dog.age && Objects.equals(name, dog.name) && Objects.equals(type, dog.type);
    }
3.1.3 示例代码运行截图

在这里插入图片描述

3.2 编译器自动生成

3.2.1 idea篇
生成过程
a 按下Alt+Insert键

在这里插入图片描述

b 选择equals()和hashCode()方法

在这里插入图片描述

c 选择需要比较的属性,然后一直next下去(直到没有next按钮)

在这里插入图片描述

d 点击finish按钮

在这里插入图片描述

示例代码
Dog类
package Work;

import java.util.Objects;

public class Dog {
    private String name;
    //名字
    private String type;
    //类型
    private int age;
    //年龄

    public Dog() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public boolean equals(Object o) {
        //如果条件判断里面的内容只有一行,则可以省略{}不写,但是写代码时不建议这么干
        //因为这样的话逻辑很有可能把自己给绕晕的
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Dog dog = (Dog) o;
        return age == dog.age && Objects.equals(name, dog.name) && Objects.equals(type, dog.type);
    }
//暂时不用管hashCode方法
    @Override
    public int hashCode() {
        return Objects.hash(name, type, age);
    }
}

Test类
package Work;
public class Test {
    public static void main(String[] args) {
        Dog d1=new Dog("旺财","金毛",10);
        Dog d2=new Dog("旺财","金毛",10);
        Dog d3=new Dog("旺财","边牧",10);
        System.out.println("d1与d2是同一只狗吗?"+d1.equals(d2));
        System.out.println("d2与d3是同一只狗吗?"+d2.equals(d3));
    }
}
示例代码运行截图

在这里插入图片描述

3.2.2 eclipse篇
生成过程
a 按下Alt+Shift+S快捷键

在这里插入图片描述

b 选择hashCode() and equals()方法

在这里插入图片描述

c 选择需要比较的属性

在这里插入图片描述

d 点击Generate按钮即可

在这里插入图片描述

示例代码

Dog类

public class Dog {
	private String name;
	// 名字
	private String type;
	// 类型
	private int age;

	// 年龄
	public Dog() {
		// TODO Auto-generated constructor stub
	}

	public Dog(String name, String type, int age) {
		super();
		this.name = name;
		this.type = type;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
    //hashCode先不管,java API文档中说重写equals方法建议也一并重写了hashCode方法
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((type == null) ? 0 : type.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Dog other = (Dog) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (type == null) {
			if (other.type != null)
				return false;
		} else if (!type.equals(other.type))
			return false;
		return true;
	}

	
    
}

Test类

public class Test {
	public static void main(String[] args) {
	     Dog d1=new Dog("旺财","金毛",10);
	     Dog d2=new Dog("旺财","金毛",10);
	     Dog d3=new Dog("旺财","边牧",10);
	     System.out.println("d1与d2是同一只狗吗?"+d1.equals(d2));
	     System.out.println("d2与d3是同一只狗吗?"+d2.equals(d3));
	}
}

示例代码运行截图

在这里插入图片描述

3.3 应该选哪种?

3.3.1 如何选择

开发当中,一般用编译器生成

3.3.2 注意的两点
a 只要是自定义的类里面一定要重写equals方法,因为其他类可能会需要进行该类的内容的比较
b 一定要熟悉equals方法的两种思路,学习别人好的思路,可以精简代码的同时又能够提升自己程序的健壮性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SSS4362

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值