提问者:小点点

龙目岛@EqualsAndHashCode一个有列表的类


@EqualsAndHashcode
class MyClass {
    String property1;
    List<NewClass> newClassList;
}
@EqualsAndHashcode
class NewClass {
    String abc;
    String xyz;
}

如果我比较< code>MyClass(用< code>@EqualsAndHashcode注释)的两个对象是否相等,是否会检查< code>newClassList属性的顺序?


共2个答案

匿名用户

通过使用@EqualsAndHashcode它将传播到使用newClassList.equals(…)方法,根据java doc

接口列表

boolean equals(Object o)将指定对象与此列表进行比较是否相等。当且仅当指定对象也是列表时返回true,两个列表具有相同的大小,并且两个列表中所有对应的元素对都相等。(两个元素e1和e2是相等的if(e1==null? e2==null:e1.equals(e2))。)换句话说,如果两个列表以相同的顺序包含相同的元素,则它们被定义为相等。该定义确保equals方法在List接口的不同实现中正常工作。

如果您想要一个列表不检查顺序的自定义功能,那么您必须删除@EqualsAndHashcode,并根据需要提供您自己的等于方法。

您想要的功能将以一种简单的方式

(list1 != null && list2 != null && list1.size() == list2.size() && list1.containsAll(list2) && list2.containsAll(list1) ) || (list1 == null && list2 == null)

这将引导我们到以下等于方法

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        NewClass newClass = (NewClass) o;
        return Objects.equals(property1, newClass.property1) &&
                ((newClassList != null && newClass.newClassList != null && newClassList.size() == newClass.newClassList.size() && newClassList.containsAll(newClass.newClassList) && newClass.newClassList.containsAll(newClassList) ) || (newClassList == null && list2 == null));
               
    }

也不要忘记手动覆盖hashcode方法。

匿名用户

这取决于你想要什么类型的比较。比较[1,1,2]==[1,2,2]应该返回true吗?如果是,那么您可以将列表转换为set(也许您也应该在类中使用Set):

public boolean equals(Object o) {
  if (this == o) return true;
  if (o == null || getClass() != o.getClass()) return false;
  MyClass that = (MyClass) o;
  if (this.newClassList == null && that. newClassList == null) return true;
  if (this.newClassList != null && that.newClassList != null
      && this.newClassList.size() == that.newClassList.size()) {
    return new HashSet(this.newClassList).equals(new HashSet(that.newClassList));
  }
  return false;
}

否则,您必须对列表中的元素进行排序并进行比较:

public boolean equals(Object o) {
    // same code as before, except the HashSet part
    List<NewClass> one = new ArrayList<NewClass>(this.newClassList); 
    List<NewClass> two = new ArrayList<NewClass>(that.newClassList);   
    Collections.sort(one);
    Collections.sort(two);      
    return one.equals(two);

另外,您必须为NewClass定义自己的比较器,因此sor方法知道如何对元素进行排序。