Java 8 Lambda-两个列表的交集

Java 8 Lambda-两个列表的交集,java,lambda,java-8,intersection,Java,Lambda,Java 8,Intersection,我试图根据某些条件找到两个列表的交集,并执行一些步骤。找不到方法(在学习阶段):) Double totalAmount=0.00d; 双倍折扣=0.00d; List orderLineEntryList=orderEntry.getOrderReleases().stream() .flatMap(orderReleaseEntry->orderReleaseEntry.getOrderLines().stream()) .filter(orderLineEntry->orderLineEn

我试图根据某些条件找到两个列表的交集,并执行一些步骤。找不到方法(在学习阶段):)

Double totalAmount=0.00d;
双倍折扣=0.00d;
List orderLineEntryList=orderEntry.getOrderReleases().stream()
.flatMap(orderReleaseEntry->orderReleaseEntry.getOrderLines().stream())
.filter(orderLineEntry->orderLineEntry.getStatus().equals(“PP”)| | orderLineEntry.getStatus().equals(“PD”))
.collect(Collectors.toList());
对于(OrderLineEntry OrderLineEntry:orderLineEntryList){
对于(SplitLineEntry SplitLineEntry:splitReleaseEntry.getLineEntries()){
if(splitLineEntry.getOrderLineId().equals(orderLineEntry.getId())&&splitLineEntry.getStatusCode()!=“PX”){
totalAmount+=orderLineEntry.getFinalAmount();
couponDiscount+=orderLineEntry.getCouponDiscount()==null?0.00d:orderLineEntry.getCouponDiscount();
}
}
}
如你所见,逻辑很简单


根据一些过滤器
列表
从订单中获取所有项目,并与另一个
列表
相交,然后做一些事情。

最简单的方法是:

List<T> intersect = list1.stream()
                         .filter(list2::contains)
                         .collect(Collectors.toList());
List intersect=list1.stream()
.filter(列表2::包含)
.collect(Collectors.toList());
我需要在假设list1.id==list2.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();
        });
Set orderLineEntrSet=orderEntry.getOrderReleases().stream()
.flatMap(orderReleaseEntry->
orderReleaseEntry.getOrderLines().stream())
.filter(orderLineEntry->{
字符串s=orderLineEntry.getStatus();
返回“PP.equals(s)| |“PD.equals(s)”;
})
.map(e->e.getId())
.collect(收集器.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();
});
您可以通过使用reduce函数来避免使用对数组对象的引用。例如,查看Collectors.averagingDouble是如何实现的。但我发现这更复杂

注意:这是O(N),使用一组ID,而不是使用匹配ID的列表,该列表将是O(N^2)

list intersect=list1.stream().filter(set1::contains).collect(Collectors.toList());


只要
T
String
Integer
Float
,在equals和HashCode方法简单的情况下,这就可以工作。但是如果
T
是一个自定义对象,我们需要实现HashCode&equals

,找到交集的最有效方法是使用集合或映射。我建议你你可以通过收集一个合适的groupingBy来建立一个集合。@PeterLawrey,你能帮我用Lambda实现同样的功能吗?我创建列表只是为了找到交集。典型的Java编码,我会使用
映射
:)我已经看到了这个例子。我如何在我的用例中使用它。由于
list1
和list2是不同类型的,我需要在假设
list1.id==list2.fk_id
上对它们进行比较,作为一种优化,我会首先将list2转换为哈希集。contains是O(n),所以这是一个O(n^2)集交集操作我已经尝试过了,但我认为::contains use==而不是equals,结果交集可能为空。我们需要为T实现HashCode&equals,以便交集工作正常。不确定O(N)。由于您需要在第二个列表中使用“contains”,我认为这仍然是O(N^2)。@HakunaM Set.contains使用哈希集是O(1)摊销(对于树集是O(logn))收集器。toSet()返回一个哈希集。一年后添加的这个答案,除了更冗长、格式更少之外,与投票结果相同。。
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();
        });