Java 比较两个对象总是返回false

Java 比较两个对象总是返回false,java,object,compare,equals,Java,Object,Compare,Equals,我正在尝试创建一个简单的日期类。我的教授还希望我们在date类中包含自己的.equals方法,它应该比较两个对象。我的问题是我的方法返回false,除非我比较完全相同的对象,即使它们的值相同 这是我的司机: public class Lab3Driver { public static void main(String[] args) { Date theDate = new Date(6, 30, 1995); Date anotherDate = new Dat

我正在尝试创建一个简单的日期类。我的教授还希望我们在date类中包含自己的.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;
    }

这很正常,因为你写了

else {
   return false;
}
因此,每当该对象具有不同的引用并且来自同一个类时,您就会进入上面返回false的else语句。 您应该实现代码,而不是返回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() && ...;
}
此行不比较对象。这只会验证对象是否在相同的内存空间中,基本上是询问它是否是指向相同位置的完全相同的对象

如果要比较两个不同的对象,请使用以下两个不同的实例

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

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

正如内特已经说过的,你必须比较你正在比较的两个对象的各个字段。Tοdοu可以使用return year==that.getYear&&day==that.getDay&&mοnth==that.getMοnth

但是等等!Yοur等于methοd接收一个对象。因此,我们不能使用这些方法。你有两种方法可以解决这个问题

在methοD的开始处执行实例检查,然后强制转换参数tοa Dateοobject。 仅限制所有日期对象的yοur methodοd参数。
当然,我也可以选择后者,因为如果你使用了一个n-Date对象,那么错误会在最后时刻出现。无论如何,如果你在methοd中做了一个类型检查,并且如果类型检查失败,那么你可能永远不会犯错误,如果你在调用方法之前提供了一个不是日期对象的参数。

有一件事你需要确保,如果你覆盖equals方法,你也应该覆盖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;
    }

考虑哪些情况将允许您的方法返回True只是检查它们是否是同一个对象,而不是它们的值是否相等。您需要比较类的所有字段。那么,您实际在哪里比较对象呢?基本上,equals方法基本上是返回this==that;。
Date theDate = new Date(6, 30, 1995);
Date anotherDate = new Date(6, 30, 1995);
    @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;
    }