比较两个 objects 总是 returns false
Comparing two objects always returns false
我正在尝试创建一个简单的日期 class。我的教授还希望我们在日期 class 中包含我们自己的 .equals 方法,它应该比较两个 object。我的问题是我的方法 returns 错误,除非我比较完全相同的 object,即使它们的值相同。
这是我的 driver:
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);
}
}
这是我的约会对象class:
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;
}
很正常,因为你写了
else {
return false;
}
因此,只要 that
对象具有不同的引用并且来自同一个 class,您就会进入上面的 else 语句,其中 returns 为 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() && ...;
}
if (this == that)
这一行不比较对象。这只验证你的对象是否在同一个内存中space,基本上是询问它是否完全相同的对象(指向同一个地方)。
如果你想比较两个不同的对象,两个不同的实例,比如
Date theDate = new Date(6, 30, 1995);
Date anotherDate = new Date(6, 30, 1995);
那么您必须添加更多代码行来检查每个对象中每个变量的每个值,或者覆盖“==”方法以使其比较这些值。
其他一些注意事项:
正如 Nate 已经说过的,您必须比较您正在比较的两个对象的各个字段。为此,您可以使用 return year == that.getYear() && day == that.getDay() && mοnth == that.getMοnth()
。
但是等等!你的 equals
方法接受一个 Object
。因此,我们不能使用那些方法。有两种方法可以解决这个问题。
- 在方法的开头进行
instanceοf
检查,然后将参数转换为Date
对象。
- 限制你的方法的参数只允许
Date
个对象。
就我个人而言,我会选择后者,因为如果您使用非Date
对象,编译时会弹出错误。但是,如果您在方法中进行了类型检查并在类型检查失败时抛出异常,并且在调用该方法之前提供的参数不是 Date
对象,您可能永远不会注意到错误。
有一件事你需要确保,如果你覆盖 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;
}
我正在尝试创建一个简单的日期 class。我的教授还希望我们在日期 class 中包含我们自己的 .equals 方法,它应该比较两个 object。我的问题是我的方法 returns 错误,除非我比较完全相同的 object,即使它们的值相同。
这是我的 driver:
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);
}
}
这是我的约会对象class:
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;
}
很正常,因为你写了
else {
return false;
}
因此,只要 that
对象具有不同的引用并且来自同一个 class,您就会进入上面的 else 语句,其中 returns 为 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() && ...;
}
if (this == that)
这一行不比较对象。这只验证你的对象是否在同一个内存中space,基本上是询问它是否完全相同的对象(指向同一个地方)。
如果你想比较两个不同的对象,两个不同的实例,比如
Date theDate = new Date(6, 30, 1995);
Date anotherDate = new Date(6, 30, 1995);
那么您必须添加更多代码行来检查每个对象中每个变量的每个值,或者覆盖“==”方法以使其比较这些值。
其他一些注意事项:
正如 Nate 已经说过的,您必须比较您正在比较的两个对象的各个字段。为此,您可以使用 return year == that.getYear() && day == that.getDay() && mοnth == that.getMοnth()
。
但是等等!你的 equals
方法接受一个 Object
。因此,我们不能使用那些方法。有两种方法可以解决这个问题。
- 在方法的开头进行
instanceοf
检查,然后将参数转换为Date
对象。 - 限制你的方法的参数只允许
Date
个对象。
就我个人而言,我会选择后者,因为如果您使用非Date
对象,编译时会弹出错误。但是,如果您在方法中进行了类型检查并在类型检查失败时抛出异常,并且在调用该方法之前提供的参数不是 Date
对象,您可能永远不会注意到错误。
有一件事你需要确保,如果你覆盖 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;
}