Java类对象的equals和hashCode相关知识

1. equals介绍

Object中的equals方法用于检测一个对象是否等于另外一个对象,如果两个对象的引用相等,则两对象相等。
假设有下面的Staff类:

public class Staff{
	private String name;
	private int age;
	private double salary;
	
	public Staff(String name, int age, double salary){
		this.name = name;
		this.age = age;
		this.salary = salary;
	}
	//......其他相关代码

	public static void main(String[] args){
		Staff s = new Staff("张三", 25, 8000);
		Staff s2 = new Staff("张三", 25, 8000);
		Staff s3 = s;
		
		//输出为false
		System.out.println(s.equals(s2));

		//输出为true
		System.out.println(s.equals(s3));
	}	
}

上面的输出结果原因为:Staff类没用重写Object的equals方法,默认需要引用相同,才能返回true。若想使equals是根据内容来进行比较的,则需要重写Object的equals方法。

public class Staff{
	private String name;
	private int age;
	private double salary;
	
	public Staff(String name, int age, double salary){
		this.name = name;
		this.age = age;
		this.salary = salary;
	}
	
	//重写Object的equals方法
	@Override
	public boolean equals(Object otherObject){
		//若两个对象地址相同,返回true
		if (this == otherObject) return true;
		//若比较的对象是null,则返回false
		if (otherObject == null) return false;
		//另外的对象必须是Staff类型,若可以接受其子类型则使用 instanceof
		if (this.getClass() != otherObject.getClass()) return false;
		
		//进行强致类型转换
		Staff other = (Staff)otherObject;
		
		//若name、age、salary相同则返回true.  对象之间用equals进行比较,基本类型之间用==进行比较
		return this.name.equals(other.name) && this.age == other.age && this.salary == other.salary;
	}	
	//......其他相关代码

	public static void main(String[] args){
		Staff s = new Staff("张三", 25, 8000);
		Staff s2 = new Staff("张三", 25, 8000);
		Staff s3 = s;
		
		//此时输出为true,对象内容相同,则认为是相等。
		System.out.println(s.equals(s2));

		//输出为true
		System.out.println(s.equals(s3));
	}	
}

若不太了解Java的基本数据类型,请阅读:Java数据类型相关知识

在用户自定义类中重写equals方法可以根据需求来对类对象进行相等性判断。

当上面的name为null时,调用this.name.equals(other.name)即在一个null对象上面调用方法,会出现的错误,避免错误则需把上面的equals方法改为:

public boolean equals(Object otherObject){
	//若两个对象地址相同,返回true
		if (this == otherObject) return true;
		//若比较的对象是null,则返回false
		if (otherObject == null) return false;
		//另外的对象必须是Staff类型,若可以接受其子类型则使用 instanceof
		if (this.getClass() != otherObject.getClass()) return false;
		
		//进行强致类型转换
		Staff other = (Staff)otherObject;
		
		//使用Objects类的静态方法equals来判断对象是否相等。基本数据类型可以直接使用==进行判断。
		return Objects.equals(this.name, other.name) && this.age == other.age && this.salary == other.salary;

Objects.equals(a, b)方法接收两个参数,若两个参数都为null则返回true,其中一个为null返回false,不为null则调用a.equals(b);

拓展:Java语言规范要求equals方法具有下面的特性:

  1. 自反性:对于任何的非空引用x, x.equals(x)应该返回true;
  2. 对称性:对于任何引用x和y,当且仅当y.equals(x)返回true时,x.equals(y)返回true。
  3. 传递性:对于任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,x.equals(z)也应该返回true。
  4. 一致性:如果x和y引用对象没有发生变化,反复调用x.equals(y)应该返回同样的结果。
  5. 对于任意的非空引用x,x.equals(null)应该返回false。
2. hashCode介绍

散列码(hash code) 是由对象导出的一个整型值。散列码是没用规律的。如果x和y是两个不同的对象,x.hashCode() 与 y.hashCode() 基本上是不会相同。在Object中每个对象都有一个默认的散列码,其值是由对象的存储地址得出的。(String类型除外)
注:字符串的散列码是由内容推到出来的。
在这里插入图片描述
如果重写了equals方法,就必须为用户可能插入散列表的对象重新定义hashCode方法。

public class Staff{
	//...
	public int hashCode(){
		return 7*name.hashCode() + 11*Integer(age).hashCode() + 13*Double(salary).hashCode();
}

上面的age和salary为基本数据类型,需转换为包装类型才能调用hashCode方法。
为防止name为null,则可改为:

return 7*Objects.hashCode(name) + 11*Integer(age).hashCode() + 13*Double(salary).hashCode();

也可进一步简写为:

return Objects.hash(name, age, salary);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值