【问题标题】:Comparing two objects always returns false比较两个对象总是返回 false
【发布时间】:2019-01-26 19:56:53
【问题描述】:

我正在尝试创建一个简单的日期类。我的教授还希望我们在应该比较两个对象的日期类中包含我们自己的 .equals 方法。我的问题是我的方法返回 false,除非我比较完全相同的对象,即使它们的值相同。

这是我的司机:

public class Lab3Driver {

    public static void main(String[] args) {
     Date theDate = new Date(6, 30, 1995);
     Date anotherDate = new Date(6, 30, 1995);
     System.out.println(theDate.equals(anotherDate));
     System.out.println(theDate);
     System.out.println(anotherDate);
    }
}

这是我的约会课程:

public class Date {
    private int month;
    private int day;
    private int year;
    public Date() // default no arg constructor
    {
        this.month = 1; // set to date I completed this class, for fun.
        this.day = 26;
        this.year = 2019;
    }

    public Date(int m, int d, int y) // normal constructor in case you want to initialize variables upon object declaration
    {
        this.month = m;
        this.day = d;
        this.year = y;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month)
    {
        if (month >= 1 && month <= 12) // if else that checks and makes sure months are between 1 and 12
        {
            this.month = month;
        }
        else
        {
            System.out.println("Invalid month input. Months are between 1 and 12.");
        }
    }

    public int getDay()
    {
        return day;
    }

    public void setDay(int day)
    {
        if (day >= 1 && day <= 31) // if else that checks and makes sure days are between 1 and 31
        {
            this.day = day;
        }
        else
        {
            System.out.println("Invalid day input. Days are between 1 and 31.");
        }
    }

    public int getYear()
    {
        return year;
    }

    public void setYear(int year) // year can be set to anything, in the case that this program is used for something
    {                             // other than the present day, as in a reference to the past or future
        this.year = year;
    }

    public String toString() // to string in order to print out the date that is stored
    {
        String theDate = "The date is: " + this.month + "/" + this.day + "/" + this.year;
        return theDate;
    }

    public boolean equals(Object that) // compares two objects and checks for null/type casting
    {
        if (this == that)
            return true;
        else if(that == null || that.getClass()!= this.getClass())
        {
            System.out.println("Null or type casting of argument.");
            return false;
        }
        else
            return false;
    }

我认为这种方法会产生问题:

 public boolean equals(Object that) // compares two objects and checks for null/type casting
    {
        if (this == that)
            return true;
        else if(that == null || that.getClass()!= this.getClass())
        {
            System.out.println("Null or type casting of argument.");
            return false;
        }
        else
            return false;
    }

【问题讨论】:

  • 想想什么情况下可以让你的方法返回 True。 == 只检查它们是否实际上是同一个对象,而不是它们是否具有相等的值。您需要比较该类的所有字段。
  • 好吧,你在哪里实际上比较对象?基本上无处可去,你的equals方法基本上就是return this == that;

标签: java object compare equals


【解决方案1】:

这很正常,因为你写了

else {
   return false;
}

因此,每当that 对象具有不同的引用并且来自同一个类时,您就会在上面的 else 语句中返回 false。 你应该实现代码而不是返回false,例如:

public boolean equals(Object that) // compares two objects and checks for null/type casting
{
    if (this == that)
        return true;
    else if(that == null || that.getClass()!= this.getClass())
    {
        System.out.println("Null or type casting of argument.");
        return false;
    }
    else
        return this.year == that.getYear() && ...;
}

【讨论】:

    【解决方案2】:
    if (this == that)
    

    此行不比较对象。这只是验证你的对象是否在同一个内存空间,基本上是询问它是否是完全相同的对象(指向同一个地方)。

    如果你想比较两个不同的对象,比如两个不同的实例

    Date theDate = new Date(6, 30, 1995);
    Date anotherDate = new Date(6, 30, 1995);
    

    然后您必须添加更多代码行来检查每个对象中每个变量中的每个值,或者覆盖“==”方法以使其比较值。

    【讨论】:

      【解决方案3】:

      其他需要注意的事项:

      正如 Nate 已经说过的,您必须比较您正在比较的两个对象的各个字段。为此,您可以使用return year == that.getYear() &amp;&amp; day == that.getDay() &amp;&amp; mοnth == that.getMοnth()

      但是等等!您的equals 方法采用Object。因此,我们不能使用那些方法。有两种方法可以解决此问题。

      1. 在方法的开头检查instanceοf,然后将参数转换为Date οbject。
      2. 将您的方法的参数限制为仅允许 Date οobjects。

      就个人而言,我会做后者,因为如果你使用非Date 对象,编译时会弹出一个错误。但是,如果您在方法中进行了类型检查并在类型检查失败时抛出异常,如果您在调用该方法之前提供的参数不是Date 对象,您可能永远不会注意到错误。

      【讨论】:

        【解决方案4】:

        您需要确保,如果您覆盖 equals 方法,您还应该覆盖 hashCode 方法。

        供您参考,请阅读该部分 https://www.baeldung.com/java-equals-hashcode-contracts#hashcode

        我已经为你完成了这两个被覆盖的方法。

            @Override
            public boolean equals(Object that) {
                if (this == that)
                    return true;
                
                if(!(that instanceof Date))
                    return false;
                
                if(that == null || that.getClass()!= this.getClass())
                    return false;
                
                Date anotherDate = (Date) that;
                if(this.month == anotherDate.month
                        && this.day == anotherDate.day
                        && this.year == anotherDate.year)
                    return true;
                
                return false;
            }
        
            @Override
            public int hashCode() {
                
                final int prime = 31;
                int result = 1;
                result = prime * result + (int) (month ^ (month >>> 16));
                result = prime * result + (int) (day ^ (day >>> 16));
                result = prime * result + (int) (year ^ (year >>> 16));
                
                return result;
            }
        

        【讨论】:

          猜你喜欢
          • 2013-12-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-25
          • 1970-01-01
          • 2017-09-05
          相关资源
          最近更新 更多