重写equals()&hashCode()&toString()—Java类设计

本文详细介绍如何在Java中正确重写equals、hashCode和toString方法,确保对象比较、散列和字符串表示的一致性,是Java开发者的必备技能。

很多时候,设计一个类,我们需要重写超类Object中的equals(Object o)、hashCode()以及toString()

  • equals(Object o):比较当前对象与指定对象o的状态(比较两个对象中所有字段的值)是否相同,是即返回true,否则返回false
  • hashCode():获得当前对象的散列码,超类Object中定义的hashCode()会将对象的存储地址作为散列码返回
  • toString():为方便操作而存在,可用于打印对象的状态信息

那么,它们三儿具体应该怎么搞呢?


一、User类

定义一个用于测试的类User,包含两个字段以及对应的get/set方法
- age:用户年龄,int类型
- name:用户名字,String类型
class User{
	private int age;
	private String name;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

二、重写equals(Object o)

设计步骤:
1. 用“==”判断对象o与当前对象是否为同一个对象,若是则直接返回true
2. 若对象o为null,则直接返回false
3. 根据情况选择使用getClass()方法或instanceOf关键字来判断对象o与当前对象是否为同一类型,若不是则返回false
4. 使用强制类型转换将对象o转化为当前对象类型
5. 依次判断对象o与当前对象中的所有对应字段是否相同,若全部相同则返回true
代码:
class User{
	private int age;
	private String name;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@override
	public boolean equals(Object o) {
		if(this==o)return true;//1、用“==”判断对象o与当前对象是否为同一个对象,若是则直接返回true
		if(o==null)return false;//2、 若对象o为null,则直接返回false
		if(!(getClass()==o.getClass()))return false;//3、使用getClass()方法来判断对象o与当前对象是否为同一类型,若不是则返回false
		User user=(User)o;//4、使用强制类型转换将对象o转化为当前对象类型User
		return user.getAge()==age&&Objects.equals(name,user.getName());//5、依次判断对象o与当前对象中的所有对应字段是否相同,若全部相同则返回true
	}
}

三、重写hashCode()

设计步骤:
1. 只要重写了equals()方法,则必须重写hashCode()
2. 当a.equals(b)返回true时,a.hashCode()==b.hashCode()也必须返回true
3. 一般直接将所有字段对应的散列码相加即可
4. 多数情况下会添加一个素数31,用于最大可能的保证散列码的唯一;当然31也可以换成7,11,13等(但一定是素数)。大多数人喜欢用31是因为hash*31可以被虚拟机优化为(hash<<5)-hash
代码:
class User{
	private int age;
	private String name;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@override
	public int hashCode() {
		int hash=0;
		int 
		hash=31*hash+Integer.hashCode(age);//31也可以换成7,11,13等(但一定是素数)。大多数人喜欢用31是因为hash*31可以被虚拟机优化为(hash<<5)-hash
		hash=31*hash+Objects.hashCode(name);
		return hash;
	}
}

四、重写toString

toString()的设计就很简单了,一般都是自定义的格式。下面是java核心思想中推荐的格式来重写的toString():
代码:
class User{
	private int age;
	private String name;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@override
	public String toString() {
		return getClass().getName()+
			"[name is:"+getName()+
			",age is:"+getAge()+
			"]";
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值