第八条 覆盖equals是要遵守通用的约定
覆盖equals必须满足以下四个要求:
(1)自反性
对于任何非null的引用值x,x.equals(x)返回true
(2)对称性
对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,
x.equals(y)必须返回true
(3)传递性
对于任何非null的引用值x、y和z,如果x.equals(y)返回true,
y.equals(z)返回true,则x.equals(z)返回true
(4)一致性
对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的
信息没有被修改,多次调用x.equals(y)就会一致的返回ture或者false
(1)自反性是最为基本的性质,所以最好完成。
(2)对称性
public class MyString {
private final String s;
public MyString(String s) {
this.s = s;
}
@Override
public boolean equals(Object o) {
if(o instanceof MyString) {
MyString cis = (MyString)o;
return s.equalsIgnoreCase(cis.s);
}
if(o instanceof String) {
return s.equalsIgnoreCase((String)o);
}
return false;
}
}
import junit.framework.Assert;
import org.junit.Test;
public class TestMyString {
@Test
public void testEquals() {
MyString ms = new MyString("P");
String s = "p";
Assert.assertEquals(ms.equals(s), true);
Assert.assertEquals(s.equals(ms), false);
}
}
说明
自反性是被违背了,所以可以将代码改为:
public class MyString {
private final String s;
public MyString(String s) {
this.s = s;
}
@Override
public boolean equals(Object o) {
if(o instanceof MyString) {
MyString cis = (MyString)o;
return s.equalsIgnoreCase(cis.s);
}
return false;
}
}
自己就和自己比较,不要贪多。
(3)传递性
public class MyPoint {
private final int x;
private final int y;
public MyPoint(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if(!(o instanceof MyPoint))
return false;
MyPoint p = (MyPoint)o;
return p.x == x && p.y == y;
}
}
import java.awt.Color;
public class MyColorPoint extends MyPoint{
private Color c;
public MyColorPoint(int x, int y, Color c) {
super(x, y);
this.c = c;
}
@Override
public boolean equals(Object o) {
if(!(o instanceof MyColorPoint))
return o.equals(this);
if(!(o instanceof MyPoint))
return false;
return super.equals(o) && ((MyColorPoint)o).c
== c;
}
}
import java.awt.Color;
import org.junit.Assert;
import org.junit.Test;
public class TestMyColorPoint {
@Test
public void testEquals() {
MyPoint p = new MyPoint(1,2);
MyColorPoint mcp1 = new MyColorPoint
(1,2,Color.BLUE);
MyColorPoint mcp2 = new MyColorPoint
(1,2,Color.RED);
Assert.assertEquals(mcp1.equals(p), true);
Assert.assertEquals(p.equals(mcp2), true);
}
}
现在满足了对称性,又丧失了传递性,所以还要修改equals方法。
总之,equals和人的思维应该是一样的,所以全面的思考可能出现的各种情况,并且根据情况写出解决方法是写好equals的关键
分享到:
相关推荐
Joshua Bloch 所著《Effective Java 第二版》一书摘要这是我对 Joshua Bloch 所著《Effective Java 第 2 ... 覆盖equals时遵守一般约定9.重写equals时务必重写hashCode10. 始终覆盖toString11.明智地覆盖克隆12.考虑实
第8章 使用规范 193 8.1 数组 193 8.2 attribute 195 8.3 集合 198 8.3.1 集合参数 199 8.3.2 集合属性与返回值 200 8.3.3 数组与集合之间的选择 204 8.3.4 自定义集合的实现 205 8.4 ICloneable ...
第8章 使用规范 193 8.1 数组 193 8.2 attribute 195 8.3 集合 198 8.3.1 集合参数 199 8.3.2 集合属性与返回值 200 8.3.3 数组与集合之间的选择 204 8.3.4 自定义集合的实现 205 8.4 ICloneable ...
- **项03:覆盖equals时请遵守通用约定**:正确的equals方法实现对于确保对象一致性至关重要。 #### 代码设计原则 - **项04:始终覆盖hashCode**:当重写了equals方法时,必须同时重写hashCode方法以保持一致性。 ...
- **历史**:Java最初是为了开发消费电子产品而设计的,后来发展成为一种通用的编程语言。 - **特点**: - **跨平台性**:Java程序可以在任何安装了Java虚拟机(JVM)的操作系统上运行,这是通过JVM实现的。 - *...