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);