Java 8 Lambda - 两个列表的交集
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31683375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 Lambda - Intersection of Two Lists
提问by Reddy
I am trying to find intersection
of two lists based on some condition and doing some steps. Couldn't find a way to do it (in learning stage) :)
我试图intersection
根据某些条件查找两个列表并执行一些步骤。找不到方法(在学习阶段):)
Double totalAmount = 0.00d;
Double discount = 0.00d;
List<OrderLineEntry> orderLineEntryList = orderEntry.getOrderReleases().stream()
.flatMap(orderReleaseEntry -> orderReleaseEntry.getOrderLines().stream())
.filter(orderLineEntry -> orderLineEntry.getStatus().equals("PP") || orderLineEntry.getStatus().equals("PD"))
.collect(Collectors.toList());
for (OrderLineEntry orderLineEntry : orderLineEntryList) {
for (SplitLineEntry splitLineEntry : splitReleaseEntry.getLineEntries()) {
if (splitLineEntry.getOrderLineId().equals(orderLineEntry.getId()) && splitLineEntry.getStatusCode() != "PX") {
totalAmount += orderLineEntry.getFinalAmount();
couponDiscount += orderLineEntry.getCouponDiscount() == null ? 0.00d : orderLineEntry.getCouponDiscount();
}
}
}
As you see, the logic is simple
如您所见,逻辑很简单
Get All items from order based on some filter list
and intersect with another list
and do some stuff.
根据某些过滤器从订单中获取所有项目list
并与另一个相交list
并做一些事情。
采纳答案by Silas Reinagel
The simplest approach is this:
最简单的方法是这样的:
List<T> intersect = list1.stream()
.filter(list2::contains)
.collect(Collectors.toList());
回答by Peter Lawrey
I need to compare them on assume list1.id == list2.fk_id
我需要在假设 list1.id == list2.fk_id 上比较它们
First build up a set of the fk_id;
首先建立一组fk_id;
Set<Integer> orderLineEntrSet = orderEntry.getOrderReleases().stream()
.flatMap(orderReleaseEntry ->
orderReleaseEntry.getOrderLines().stream())
.filter(orderLineEntry -> {
String s = orderLineEntry.getStatus();
return "PP".equals(s) || "PD".equals(s);
})
.map(e -> e.getId())
.collect(Collectors.toSet());
double[] totalAmount = { 0.0 };
double[] couponDiscount = { 0.0 };
orderLineEntryList.stream()
.flatMap(sre -> sre.getLineEntries().stream())
.filter(ole -> orderLineEntrySet.contains(ole.getOrderLineId())
.filter(ole -> !"PX".equals(ole.getStatusCode()))
.forEach(ole -> {
totalAmount[0] += ole.getFinalAmount();
if (ole.getCouponDiscount() != null)
couponDiscount[0] += ole.getCouponDiscount();
});
You can avoid using a reference to an array object by using reduce function. e.g. see how Collectors.averagingDouble is implemented. But I find this more complicated.
您可以通过使用 reduce 函数来避免使用对数组对象的引用。例如,看看 Collectors.averagingDouble 是如何实现的。但我觉得这更复杂。
Note: this is O(N) by using a set of ids rather than using a list of matching ids which would be O(N^2)
注意:这是 O(N) 通过使用一组 id 而不是使用匹配 id 的列表,这将是 O(N^2)
回答by psekar
List<T> intersect = list1.stream().filter(set1::contains).collect(Collectors.toList());
List<T> intersect = list1.stream().filter(set1::contains).collect(Collectors.toList());
This will work as long as T
is a String
, Integer
, Float
, etc. where the equals and HashCode methods are straightforward. But if the T
is a custom object, we need to implement HashCode & equals
这将工作,只要T
是String
,Integer
,Float
等在那里的equals和hashCode方法非常简单。但是如果T
是自定义对象,我们需要实现HashCode & equals