我有两个 ClassA
列表
List<ClassA> list1;
List<ClassA> list2;
我想创建 4 个列表:
List<ClassA> matchedList1;
List<ClassA> matchedList2;
List<ClassA> unmatchedList1;
List<ClassA> unmatchedList2;
其中matchedList1
和matchedList2
按顺序包含具有相同classA.name
(唯一)的项目
unmatchedList1
和 unmatchedList2
按顺序包含未配对的项目。
例如
list1 = name1, name2, name3
list2 = name4, name1, name3
matchedList1 = name1, name3
matchedList2 = name1, name3
unmatchedList1 = name2
unmatchedList2 = name4
是否有任何 lambda 表达式可以根据某些谓词对两个列表中的项目进行配对?
最佳答案
当您添加 lambda
标记时,我认为您对 Java-8 解决方案感到满意。请注意,您的 matchedList1
和 unmatchedList1
包含 list1
中的所有元素,因此您实际上需要对 list1
进行分区根据 list2
中具有相同元素的谓词。这可以使用 partitioningBy
收集器来完成:
Map<Boolean, List<ClassA>> map1 = list1.stream().collect(
Collectors.partitioningBy(e1 -> list2.stream().anyMatch(
e2 -> e1.name.equals(e2.name))));
List<ClassA> matchedList1 = map1.get(true);
List<ClassA> unmatchedList1 = map1.get(false);
您可以以完全相同的方式创建 matchedList2
和 unmatchedList2
:
Map<Boolean, List<ClassA>> map2 = list2.stream().collect(
Collectors.partitioningBy(e2 -> list1.stream().anyMatch(
e1 -> e1.name.equals(e2.name))));
List<ClassA> matchedList2 = map2.get(true);
List<ClassA> unmatchedList2 = map2.get(false);
请注意,此解决方案效率不高:其复杂度为O(list1.size()*list2.size())
。如果您担心效率,最好先构建两个列表中的名称集。
或者,如果您的列表已按 name
字段预先排序,您可以使用二分搜索来加速该过程:
Comparator<ClassA> comparator = Comparator.comparing(e -> e.name);
Map<Boolean, List<ClassA>> map1 = list1.stream().collect(
Collectors.partitioningBy(e1 -> Collections.binarySearch(list2, e1, comparator) >= 0));
List<ClassA> matchedList1 = map1.get(true);
List<ClassA> unmatchedList1 = map1.get(false);
Map<Boolean, List<ClassA>> map2 = list2.stream().collect(
Collectors.partitioningBy(e2 -> Collections.binarySearch(list1, e2, comparator) >= 0));
List<ClassA> matchedList2 = map2.get(true);
List<ClassA> unmatchedList2 = map2.get(false);
关于java - 如何将两个列表中的项目配对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31098518/