我有两个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
按顺序包含未配对的商品。
e.g。
list1 = name1, name2, name3
list2 = name4, name1, name3
matchedList1 = name1, name3
matchedList2 = name1, name3
unmatchedList1 = name2
unmatchedList2 = name4
是否有任何lambda表达式根据某个谓词来配对两个列表中的项目?
答案 0 :(得分:2)
当您添加lambda
标记时,我认为您可以使用Java-8解决方案。请注意,您的matchedList1
和unmatchedList1
包含list1
中的所有元素,因此您实际上需要根据{{list1
中具有相同元素的谓词对list2
进行分区。 1}}。这可以使用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);