我有一个课程MySchool

public class MySchool{
    private long timestamp;
    private SchoolEvent event;
    private Object value;

    //getter & setters
    ...

    @Override
    public String toString() {
        return "MySchool [timestamp=" + timestamp + ", event="
                + event + ", value=" + value + "]";
    }
}


SchoolEvent是一个枚举类型:

public static enum SchoolEvent {
        CEREMONY, HOLIDAY
    }


我尝试使用Assert.assertEquals()比较两个学校列表:

List<MySchool> schoolList1 = generateSchools();
List<MySchool> schoolList2 = readSchoolsFromFile();

Assert.assertEquals(schoolList1, schoolList2);


失败,出现以下错误:

expected: java.util.ArrayList<[MySchool [timestamp=0, event=CEREMONY, value=null], MySchool [timestamp=0, event=HOLIDAY, value=null]]>

but was:  java.util.ArrayList<[MySchool [timestamp=0, event=CEREMONY, value=null], MySchool [timestamp=0, event=HOLIDAY, value=null]]>


我不明白为什么错误听起来不像是错误,我的意思是只检查错误消息,两个列表中每个元素对象的每个字段都是euqal。

我还检查了有关List#equal的Java文档,它还说:


  如果两个列表包含相同的元素,则定义为相等
  以相同的顺序。


为什么assertEquals()失败了?

最佳答案

我不明白为什么错误听起来不像是错误,我的意思是只检查错误消息,两个列表中每个元素对象的每个字段都是euqal。


是的,但这并不意味着这些对象被视为相等。

您需要覆盖equals()(和hashCode()),以便将不同的对象视为相等。默认情况下,equals方法仅检查对象身份...换句话说,x.equals(y)等效于检查xy默认情况下是否引用完全相同的对象。如果您想要不同的行为(以便检查某些字段是否相等),则需要在equals()中指定该行为,并以与之一致的方式实现hashCode()

请注意,此问题根本不依赖于集合。如果比较单个对象,则会遇到相同的问题:

MySchool school1 = schoolList1.get(0);
MySchool school2 = schoolList2.get(0);
Assert.areEqual(school1, school2); // This will fail...

10-08 08:49
查看更多