比较具有多个列表属性的两个对象的最佳方法是什么

What is the best way to compare two objects having multiple list attributes

我有一个 POJO/DTO class 具有多个列表属性,例如

class Boo {    
    private List<Foo> foos;
    private List<Integer> pointers;
}

我想比较两个列表是否包含相同的值而忽略列表的顺序。是否可以在不打开对象并对列表进行排序的情况下实现这一点?

帮助将不胜感激。提前致谢

这归结为比较列表。如果项目的顺序无论如何都无关紧要,那么使用 Set 而不是 List 可能会更好。

你的 equals 看起来像

public boolean equals(object other) {
    //here be class and null checks
    return foos.equals(other.foos) && pointers.equals(other.pointers);
}

如果您不能使用 Set - 要么是因为您可以多次拥有相同的项目,要么是因为顺序很重要 - 您可以通过相互 containsAll() 调用来执行与上述相同的操作。这仍然不会考虑重复条目,但在其他情况下会工作得很好。

您声明无法编辑 class Boo。一种解决方案是拥有一项服务 class ,它为您执行此操作有点类似于 Objects.equals().

class BooComparer {

    public static bool equals(Boo a, Boo b) {
        //again do some null checks here
        return a.foos.containsAll(b.foos) 
          && b.foos.containsAll(a.foos)
          && a.pointers.containsAll(b.pointers)
          && b.pointers.containsAll(a.pointers)
    }
}

如果这对您有用 - 很好。也许你也必须比较其他成员。再说一遍:如果其中一个列表有两次条目,这将被忽略。

"I want to compare if both contains same values instead of the order of list."

没有通用的相等运算符。有时您希望通过某些属性比较对象。可能典型的例子是比较字符串,有时 "computer" 等于或不等于 "Computer" 或 "Vesterålen" 等于或不等于 "Vesteralen".

Java中,可以重新定义之间的默认等价关系对象(修改默认行为!)。

对象 List 使用包含对象的默认等价关系作为默认等价关系,并按顺序检查是否相等。

下面的例子只忽略一个元素的顺序属性:

class My {
    private final List<String> xs;
    private final List<Integer> ys;

    My(List<String> xs, List<Integer> ys) {
        this.xs = xs;
        this.ys = ys;
    }

    public List<Integer> getYs() {
        return ys;
    }

    public List<String> getXs() {
        return xs;
    }

    @Override
    public int hashCode() {
        return xs.hashCode() + 7 * ys.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if(!(obj instanceof My))
            return false;
        My o = (My) obj;
        return
                // ignoring order
                getXs().stream().sorted().collect(toList()).equals(o.getXs().stream().sorted().collect(toList()))
                // checking order
                && getYs().equals(o.getYs());
    }
}

public class Callme {
    public static void main(String... args) {
        My m1 = new My(asList("a", "b"), asList(1, 2));
        My m2 = new My(asList("b", "a"), asList(1, 2));
        My m3 = new My(asList("a", "b"), asList(2, 1));
        System.out.println(m1.equals(m2));
        System.out.println(m1.equals(m3));
    }
}

有输出

true
false

但是我无法定义你需要的等价关系,例如,如果一个列表包含的元素多于另一个但也许你希望(例如对你等于 {a, b, a}{b, a}).

因此,为您的对象定义等价关系并覆盖 hashCodeequals