比较Java中两个对象的内容

比较Java中两个对象的内容,java,oop,equals,Java,Oop,Equals,我试图在同一类的两个对象之间进行比较。实际上,我想比较两个对象的内容。在这里,对象是班级学生。在学生课堂上,我重写了equals()方法,如下所示。 这样做,我的意图会实现吗(比较两个学生的姓名和生日)?如果不是,这里发生了什么? 问题是我没有得到我期望的答案。输出为false,即使它必须为true public class Main { public static void main(String[] args) { Student a = new Student(&

我试图在同一类的两个对象之间进行比较。实际上,我想比较两个对象的内容。在这里,对象是班级学生。在学生课堂上,我重写了
equals()
方法,如下所示。 这样做,我的意图会实现吗(比较两个学生的姓名和生日)?如果不是,这里发生了什么? 问题是我没有得到我期望的答案。输出为
false
,即使它必须为
true

public class Main {

    public static void main(String[] args) {
        Student a = new Student("John", "Johnny");
        Student b = new Student("John", "Johnny");
        a.setBirthDate(10, 10, 10);
        b.setBirthDate(10, 10, 10);
        boolean ans = Student.equals(a, b);
        System.out.println(ans);
    }

}
我已经重写了equals方法,如下所示。但我仍然面临同样的问题。我怀疑
Date
类有问题。但问题是我不太确定。而且,我不知道如何解决这个问题。谁能告诉我这里怎么了。
提前感谢。

要使
等于
起作用,您还需要覆盖
hashCode
。进一步的相等性检查需要对对象进行实际比较

此外,任何相关对象还必须实现
hashCode
equals
方法。在这种情况下,
日期

可能代码
导入java.util.Objects;
上课日期{
公众国际日;
公众月;
公共国际年;
公开日期(整数d、整数m、整数y){
这一天=d;
本月=m;
今年=y;
}
@凌驾
公共布尔等于(对象o){
if(this==o){
返回true;
}
如果(o==null | | getClass()!=o.getClass()){
返回false;
}
日期=(日期)o;
返回日期==日期.day&&
月份==日期。月份&&
年份==日期。年份;
}
@凌驾
公共int hashCode(){
返回Objects.hash(日、月、年);
}
}
公立班学生{
私有最终字符串名;
私有最终字符串lastName;
私人生日;
公立学生(字串姓氏、字串姓氏、出生日期){
this.firstName=firstName;
this.lastName=lastName;
this.birthDate=生日;
}
公共静态void main(字符串[]args){
System.out.println(新生(“约翰”,“约翰尼”,新日期(10,10,10))
.equals(新学生(“约翰”、“约翰尼”、新日期(10、10、10));
System.out.println(新生(“约翰”、“约翰尼”、新日期(11、10、10))
.equals(新学生(“约翰”、“约翰尼”、新日期(10、10、10));
}
@凌驾
公共布尔等于(对象o){
if(this==o){
返回true;
}
如果(o==null | | getClass()!=o.getClass()){
返回false;
}
学生=(学生)o;
返回Objects.equals(firstName,student.firstName)&&
Objects.equals(lastName,student.lastName)&&
对象.equals(生日,学生.birthDate);
}
@凌驾
公共int hashCode(){
返回Objects.hash(firstName、lastName、birthDate);
}
}

您可以将equals方法的结构类似于if语句。您只需要先强制转换另一个参数,然后才能比较它们的字段

@覆盖
公共布尔等于(对象o){
//检查另一个对象是否也是学生
如果(学生的实例){
//既然我们知道o是个学生,我们就可以放心地投下它了
学生其他=(学生)o;
//与编写if语句的方式类似,您可以比较每个字段。
//由于继承,我们将每个字段的相等性检查推迟到它自己的实现
返回此.firstName.equals(其他.firstName)
&&this.lastName.equals(other.lastName)
&&此.birthDate.equals(其他.birthDate);
}
//另一个物体不是学生
返回false;
}
然后,您需要在
Date
中编写类似的内容,以便在比较
生日时,它会知道该怎么做


您还可以通过使用
Objects.equals(a,b)
而不是
a.equals(b)
更进一步。如果比较时
a
恰好为空,这将确保不会得到nullPointerException。但是,由于这看起来是一个学校项目,我想您可能需要手动检查,或者假设值不会为空,而不是使用标准库。

问题是您过度编写了
equals
,但没有添加任何其他检查。目前,它只打印每个对象的值。行
返回super.equals(学生)
相当于首先不重写该方法。实现
hashCode
equals
的功能没有影响。它默认比较对象地址(例如:
this==other
)。实现
hashCode
只有在比较哈希时才有效,但由于潜在的哈希冲突,它仍然不可靠。只需编辑
equals
方法以使用getter,因为变量是私有的。由于它是一个本地方法,因此可以直接访问私有成员。我建议避免使用getter,除非您可能会错过某些功能。@AP11,实际上这将是一个有趣的讨论。通常我更喜欢在
hashCode
equals
中使用
private
字段,因为它类似于
实际状态
,而不是
视图
。getter提供了一个
视图
。但是如果
view
是期望值,那么即使是
hashCode
也应该使用
view
。否则,在某些用例中会出现差异(比如map)。正如@Locke提到的,我还建议始终直接使用属性(没有例外:)。实际上,最好使用
对象。如果
为null,则等于。进一步的
hashCode
是nee
public class Date {
    public int day;
    public int month;
    public int year;
    
    public Date(int d, int m, int y) {
        this.day = d;
        this.month = m;
        this.year = y;
    }
}
public class Student{
    private String firstName;
    private String lastName;
    private Date birthDate;
    
    public Student(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    
    public void setBirthDate(int day, int month, int year) {
        Date b_day = new Date(day, month, year);
        birthDate = b_day;
    }
}


@Override
    public boolean equals(Object student) {
        System.out.println(this.firstName);
        System.out.println(this.lastName);
        System.out.println(this.birthDate);
        
        System.out.println(((Student)student).firstName);
        System.out.println(((Student)student).lastName);
        System.out.println(((Student)student).birthDate);
        return super.equals(student);
        
    }