Java 如何使用自定义比较器比较两个数组列表是否相等?

Java 如何使用自定义比较器比较两个数组列表是否相等?,java,generics,collections,comparison,Java,Generics,Collections,Comparison,具体来说,我有两个清单: List<SystemUserWithNameAndId> list1; List<SystemUserWithNameAndId> list2; 只需实现迭代的方法,并在每次需要时重用它: public static <T> boolean areEqualIgnoringOrder(List<T> list1, List<T> list2, Comparator<? super T> comp

具体来说,我有两个清单:

List<SystemUserWithNameAndId> list1;
List<SystemUserWithNameAndId> list2;

只需实现迭代的方法,并在每次需要时重用它:

public static <T> boolean areEqualIgnoringOrder(List<T> list1, List<T> list2, Comparator<? super T> comparator) {

    // if not the same size, lists are not equal
    if (list1.size() != list2.size()) {
        return false;
    }

    // create sorted copies to avoid modifying the original lists
    List<T> copy1 = new ArrayList<>(list1);
    List<T> copy2 = new ArrayList<>(list2);

    Collections.sort(copy1, comparator);
    Collections.sort(copy2, comparator);

    // iterate through the elements and compare them one by one using
    // the provided comparator.
    Iterator<T> it1 = copy1.iterator();
    Iterator<T> it2 = copy2.iterator();
    while (it1.hasNext()) {
        T t1 = it1.next();
        T t2 = it2.next();
        if (comparator.compare(t1, t2) != 0) {
            // as soon as a difference is found, stop looping
            return false;
        }
    }
    return true;
}

public static boolean arequalignoringorder(List list1、List list2、Comparator以下是解决问题的Java 8方法。首先确保列表长度相等:

List<SystemUserWithNameAndId> list1 = ... ;
List<SystemUserWithNameAndId> list2 = ... ;

if (list1.size() != list2.size()) {
    return false;
}
在列表的索引上运行一个流,在每对上调用比较器。如果元素根据该比较器相等,则比较器返回0。如果所有元素对都是这样,则列表相等

return IntStream.range(0, list1.size())
    .allMatch(i -> comp.compare(list1.get(i), list2.get(i)) == 0);

您为什么不想重写
SystemUserWithNameAndId.equals()
?您已经重写了吗?或者您可以创建一个SystemUsersList来扩展List并重写equals,然后可以调用:list1.equals(list2);我发布的代码是测试类的一部分,我比较两个
SystemUserWithNameAndId
对象的方式不是比较它们的默认方式。您使用Java 8吗?@Radiodef我会回答,但问题还不清楚。OP是否希望根据
比较器测试两个列表是否包含相同的元素
(正如JBNizet所假设的那样),或者
比较器
只是测试两个列表是否包含与
相等的相同元素的一种方法吗?在这个问题中,OP使用
比较器
对列表进行排序,然后通过将元素与
相等()
,这没有任何意义。他说“排序后没有显式地遍历列表”-但我不知道如何实现这一点(可能将对象存储在
集合中,但对于这一点,没有提供足够的信息)。一旦编写了这种通用的可重用方法,就永远不会“显式地循环”.您“隐式循环”通过调用该方法。没有循环就无法比较列表的元素。由于JDK不提供这样的实用方法,您需要编写一个。@JBNizet这正是我希望可以避免的,但如果您确定没有实用函数来执行此操作,我将不得不使用您推荐的方法。您必须迭代最大的集合,否则AreequalingOrder将给出错误的结果。示例:列表a=[1,2,3],列表b=[1,2,3,4]。AreequalingOrder(a,b,比较器)将返回true。@TomasBartalos该方法所做的第一件事是比较列表的大小,列表的大小必须相等。感谢您花时间回答,我还没有使用Java 8,但在切换时我会记住这一点。一个小警告,我想使用不同的比较器来排序和检查是否与c相同准则是不一样的。@BruceWayne没问题。你可以很容易地在传递给
allMatch
的谓词中使用
equals
或不同的比较器。呃……虽然问题是关于比较器的,但如果只需要进行等式检查,为什么不使用一个谓词呢?
List<SystemUserWithNameAndId> list1 = ... ;
List<SystemUserWithNameAndId> list2 = ... ;

if (list1.size() != list2.size()) {
    return false;
}
Comparator<SystemUserWithNameAndId> comp =
    Comparator.comparingInt(SystemUserWithNameAndId::getSystemUserId);
list1.sort(comp);
list2.sort(comp);
return IntStream.range(0, list1.size())
    .allMatch(i -> comp.compare(list1.get(i), list2.get(i)) == 0);