Java 自定义对象上的True语句不通过?

Java 自定义对象上的True语句不通过?,java,if-statement,Java,If Statement,我有一个简单的自定义类,它只包含两个坐标 public static class CoordPoint { public int X; public int Y; public CoordPoint(){ } public CoordPoint(int X, int Y) { this.X = X; this.Y = Y; } }

我有一个简单的自定义类,它只包含两个坐标

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
}

如何计算自定义对象?

您需要重写类中的
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.
}
不会像你想的那样工作。正确实施此方法的一种方法是:

@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。我同意@antoh的说法,最好的方法是重写
equals()

简单的方法是

还检查了空对象的编辑

public boolean coordEquals(CoordPoint cp)
{

    boolean b = false;

    if(cp !=  null && this.x == cp.x && this.y == cp.y)
    {

         b = true;

    }

    return b;

}

您需要提供自己的equals实现。大概是这样的:

public boolean equals(CoordPoint a)
{
   return this.x == a.x && this.y == a.y;
}
@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;
   }
}

如果不这样做,最终将比较对象的两个引用。在本例中是不同的,因为两个引用都指向Java堆中的两个不同对象

您真正应该做的是重写(而不是重载)equals

另外,一个风格提示:字段应该是驼峰大小写,所以不是

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; // :)
    ...
}

您应该重写对象类的
equals(objecto)
方法。由于所有类都是从
Object
扩展而来,因此它们继承了这个equals方法,但有时最好为自定义类重写这个方法

如果我是你,我会这样做:

public boolean equals(CoordPoint a)
{
   return this.x == a.x && this.y == a.y;
}
@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方法,因此可以以相同的方式调用它。

您是否重写了
equals
方法?如果没有,就去做。如果需要,您的IDE可能会自动生成代码。您将对象与对象进行比较,这是不可能的,您需要比较对象中的参数,因此我建议您在code@ProgrammingNewb我能理解为什么,但在我的例子中,比较完整的对象是合乎逻辑的。对于java,难道没有更严格的方法吗?@MennoGouw第一个答案正是你想要它做的,你想要比较的是对象中的内容,而不是对象本身,因此,您可以通过比较其内部参数来比较整个对象。您还描绘了
equals
的重载。它现在不是重载,而是完全不同的方法,它违反了既定的.equals()约定。从一个对你们班不熟悉的人的角度来思考这个问题:这个人会期望.equals(otherInstanceOfClass),而不是.coordEquals(otherInstanceOfClass)@Radiodef改变了它。作为一个在C#shop工作的前java人员,它与C#非常相似。@radiodef man,我的语法真的需要一个复习。我甚至还记得如何正确重写equals方法,这让我很惊讶。看看你的方法签名。您不需要返回类型吗?我已经修复了它,但是没有@Override,它是一个静态类。我希望它属于我的Map类,一个静态类修复了这个问题。也许我应该把它移到它自己的文件里。我来自C#,在这种情况下喜欢在文件中包含多个类。据我所知,没有理由不能重写静态类中的方法。。此外,@Override注释在代码方面没有做任何事情(尽管如果方法没有重写任何内容,它会创建一个错误,所以我总是使用它)。因此,如果您在这方面遇到问题,可以删除注释。事实上,你对它有一个问题是奇怪的。