public class ChessPoint {
private int color;
private int x;
private int y;
public ChessPoint(int color, int x, int y) {
this.color = color;
this.x = x;
this.y = y;
}
//省略Setter Getter方法
}
ChessPoint point1=new ChessPoint(0,3,5);
ChessPoint point2=new ChessPoint(0,3,5);
复制代码
point1 equals point2吗?为什么? 我们的第一反应肯定是NO,point1和point2是两个不同的对象。除去简单类型,如果不去覆写hashCode方法,equals其实是和==等价的,为什么Object类会提供可覆写的equals方法呢?目的只有一个:允许程序设计者自己定义“等价关系”。
什么是等价关系,通常我们认为等价关系有3中特征:
1.自反性(a equals a)
2.对称性(如果a equals b,那么b equals a一定成立)
3.传递性(如果a equals b,b equals c,那么a equals c必须返回true)
回到上面的代码中,如果我们一定要让具有相同属性的point1“等价”point2呢?这个时候就必须覆写equals方法了。
@Override
public boolean equals(Object obj) {
ChessPoint chessPoint=(ChessPoint)obj;
return this.color==chessPoint.color&&this.x==chessPoint.x&&this.y==chessPoint.y;
}复制代码
这样就OK了吗?诚然,这个时候你再去验证point1 equals point2时是会返回true,但是请记住:
相等的对象必须具有相同的hashCode值,覆盖equals方法时一定要覆盖hashCode方法。
打印一下point1和point2的hashCode值
10-19 06:24:54.919 20559-20559/com.zoup.android.demo.equal D/point1: 10292745 10-19 06:24:54.919 20559-20559/com.zoup.android.demo.equal D/point2: 18606094
虽然我们让point1等价了point2,但是它们的hashCode值并不相等,违反了Java的通用约定。
下面是ChessPoint中hashCode()的一种覆写方法:
@Override
public int hashCode() {
int result=color;
result=31*result+x;
result=31*result+y;
return result;
}复制代码
为什么要这么写,其实没有固定的写法,只有一点要求:
为不相等的对象产生不相等的散列码。