博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重写 equals 方法
阅读量:4049 次
发布时间:2019-05-25

本文共 3366 字,大约阅读时间需要 11 分钟。

-- Start

重写 equals 方法是一件很令人头疼的事情, Java 语言规范要求 equals 方法具有下面的特性:

1. 自反性: x.equals(x)应该返回true.2. 对称性: 如果x.equals(y)返回true, 那么y.equals(x)也应该返回true.3. 传递性: 如果x.equals(y)返回true, y.equals(z)返回true, 那么x.equals(z)也应该返回true.4. 一致性: 如果对象没有变化, 反复调用equals方法应该返回相同的结果.5. x.equals(null) 应该返回false.
看上去很简单, 但是在涉及继承的时候, 稍有不慎就违反了对称性, 下面是一个例子.

public class Test {	public static void main(String[] args) {		Poeple p = new Poeple();		p.setName("ZhangSan");		p.setAge(20);		Student s = new Student();		s.setName("ZhangSan");		s.setAge(20);		s.setID(1);		System.out.println("p.equals(s) == " + p.equals(s));		System.out.println("s.equals(p) == " + s.equals(p));	}}class Poeple {	private String name;	private int age;	@Override	public boolean equals(Object otherObject) {		if (this == otherObject)			return true;		if (otherObject == null)			return false;		if (!(otherObject instanceof Poeple))			return false;		Poeple other = (Poeple) otherObject;		return name.equals(other.name) && age == other.age;	}	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;	}}class Student extends Poeple {	private int ID; // 学号	@Override	public boolean equals(Object otherObject) {		if (!super.equals(otherObject))			return false;		if (!(otherObject instanceof Student))			return false;		Student other = (Student) otherObject;		return ID == other.ID;	}	public int getID() {		return ID;	}	public void setID(int iD) {		ID = iD;	}}
结果如下:

p.equals(s) == trues.equals(p) == false
出现这种情况的原因是超类与子类有不同的比较规则, 实际的情况有以下两种:

1. 由超类决定是否相等, 如: 不管是学生还是老师, 每个人都有身份证号, 由身份证号来确定两个人是否是同一个人, 下面是一个范例程序.

class Poeple {	private int ID;	private String name;	// 由于超类决定是否相等, 可以将equals方法设置为final, 禁止子类重写	@Override	public final boolean equals(Object otherObject) {		if (this == otherObject)			return true;		if (otherObject == null)			return false;		if (!(otherObject instanceof Poeple))			return false;		Poeple other = (Poeple) otherObject;		return ID == other.ID;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public int getID() {		return ID;	}	public void setID(int iD) {		ID = iD;	}}class Student extends Poeple {	// Student 可以有自己的域}class Teacher extends Poeple {	// Teacher 可以有自己的域}
2. 子类有自己的相等概念, 下面是一个范例程序.

class Poeple {	private String name;	private int age;	@Override	public boolean equals(Object otherObject) {		if (this == otherObject)			return true;		if (otherObject == null)			return false;		if (getClass() != otherObject.getClass()) // 注意此处, 我们不能通过 instanceof 来判断			return false;		Poeple other = (Poeple) otherObject;		return name.equals(other.name) // 使用 equals 对象域				&& age == other.age; // 使用 == 比较基本类型	}	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;	}}class Student extends Poeple {	private int grade;	@Override	public boolean equals(Object otherObject) {		if (!super.equals(otherObject)) // 此处需要调用父类的 equals 方法			return false;		Student other = (Student) otherObject;		return grade == other.grade;	}}

从上面的例子可以看出, 想写出一个完美的 equals 还是很不容易的, 幸运的是 Apache Common 包有个 EqualsBuilder 类, 它能帮助我们很容易的实现 equals 方法.

--更多参见:

-- 声 明:转载请注明出处
-- Last Updated on 2012-05-18
-- Written by ShangBo on 2012-05-18
-- End

你可能感兴趣的文章
恋爱爱情婚姻家庭与炒股票
查看>>
答非所问的古今中外名人小笑话幽默
查看>>
周易、命理、风水、姓名与命运交流周易研究心得:姓名学
查看>>
解决asp.net中tabstrip不能点击的问题
查看>>
PB中使用blob进行文件读取的性能问题
查看>>
DataWindow.net中如何实现鼠标划过时变颜色
查看>>
Datawindow.net中设置字符串的显示,超过长度部分显示为。。。
查看>>
PowerBuilder中使用带返回的powerobjectparm
查看>>
从oracle表中随机取记录,产生随机数和随机字符串
查看>>
功夫熊猫,中国式的哲学和西方式的搞笑
查看>>
Oracle SYS口令深入解析
查看>>
XP中IIS“http500”错误的终极解决方法
查看>>
李开复眼中的兰迪教授:引领你的一生
查看>>
早起的虫儿被鸟吃?
查看>>
Love Your Life》—— 热爱生活
查看>>
一个高速交警的忠告
查看>>
新车装饰的中国特色
查看>>
没看过这么NB的自驾游,笑的我眼泪都出来了
查看>>
李涯的哭
查看>>
和机器学习和计算机视觉相关的数学
查看>>