我有一个只包含两个坐标的简单自定义类。
public static class CoordPoint
{
public int X;
public int Y;
public CoordPoint(){ }
public CoordPoint(int X, int Y)
{
this.X = X;
this.Y = Y;
}
}
当我有两个等于这些对象的比较时,它不会传递以下语句。
CoordPoint curPosition = new CoordPoint(5,5);
CoordPoint destination = new CoordPoint(5,5);
if (curPosition.equals(destination))
{
//This does not run
}
我应该如何评估自定义对象?
答案 0 :(得分:3)
您需要覆盖班级中的equals()
方法才能进行正确的比较。目前,如果您不覆盖它,您的班级的equals()
行为与==
运营商的行为相同。好像你写过这个:
@Override
public boolean equals(Object other) {
return this == other;
}
在你的情况下,这不是好事。这样做只有在引用进行比较时才会返回true
。所以,你的代码:
CoordPoint curPosition = new CoordPoint(5, 5);
CoordPoint destination = new CoordPoint(5, 5);
if(curPosition.equals(destination)) {
/* This won't be executed, since even though the objects have the same member
* values, the two references aren't pointing to the same object.
*/
}
CoordPoint anotherOne = curPosition;
if(curPosition.equals(anotherOne)) {
// This will be executed, since the two references point to the same object.
}
wouln按照你的意图工作。正确实现此方法的一种方法是:
@Override
public boolean equals(Object other) {
if(other == null) return false;
if(!(other instanceof CoordPoint)) return false;
CoordPoint otherPoint = (CoordPoint) other;
return (this.X == otherPoint.X) && (this.Y == otherPoint.Y);
}
第一行的检查很重要;否则,每次other
为null时,在尝试访问other
成员时返回结果的行中都会出现NullPointerException。
答案 1 :(得分:3)
你真正应该做的是覆盖(不是重载)等于。
@Override
public boolean equals(Object o){
if(! (o instanceof CoordPoint)) return false;
CoordPoint p = (CoordPoint) o;
return X == p.X && Y == p.Y;
}
另外,一个风格抬头:字段应该是驼峰式的,所以不是
public class CoordPoint{
private int X; //Capital letter X is weird here
private int Y; //Here as well
...
}
最好做
public class CoordPoint{
private int x; //Much better
private int y; // :)
...
}
答案 2 :(得分:2)
您应该覆盖Object类的equals(Object o)
方法。由于所有类都从Object
扩展,因此它们继承了此equals方法,但有时候为自定义类重写此方法是个好主意。
如果我是你,我会这样做:
@Override
public boolean equals(Object o){
if(!(o instanceof CoordPoint)) // If you're comparing an object that isn't even of the right type, return false.
return false;
else{ // Otherwise, convert o to your object and compare on whatever you want. You may want to compare x and y.
CoordPoint p = (CoordPoint) o;
if(this.x == o.x && this.y == o.y)
return true;
else
return false;
}
}
我不建议创建equals(CoordPoint p)
方法,因为那时你实际上并没有覆盖equals。这样,您使用相同的equals方法,因此可以以相同的方式调用它。
答案 3 :(得分:0)
您需要提供自己的equals实现。像这样:
public boolean equals(CoordPoint a)
{
return this.x == a.x && this.y == a.y;
}
如果你不这样做,你将最终比较对象的两个引用。在这种情况下,它们是不同的,因为两个引用都指向Java堆中的两个不同对象
答案 4 :(得分:-1)
我同意@AntonH,最好的方法是覆盖equals()
。
简单的方法是......
EDIT还检查了空对象
public boolean coordEquals(CoordPoint cp)
{
boolean b = false;
if(cp != null && this.x == cp.x && this.y == cp.y)
{
b = true;
}
return b;
}