【发布时间】:2017-07-30 23:49:34
【问题描述】:
有两个类和两个对应的列表:
class Click {
long campaignId;
Date date;
}
class Campaign {
long campaignId;
Date start;
Date end;
String type;
}
List<Click> clicks = ..;
List<Campaign> campaigns = ..;
并且想在clicks中找到所有Clicks:
在
campaigns列表中有一个对应的Campaign,即Campaign与相同的campaignIdAND这个
Campaign有type= "预期" AND这个
Campaigns.startclick.date Campaigns.end
到目前为止,我有以下实现(这对我来说似乎令人困惑和复杂):
clicks.
stream().
filter(click -> campaigns.stream().anyMatch(
campaign -> campaign.getCampaignType().equals("prospecting") &&
campaign.getCampaignId().equals(click.getCampaignId()) &&
campaign.getStart().after(click.getDate()) &&
campaign.getEnd().before(click.getDate()))).
collect(toList());
我想知道这个问题是否有更简单的解决方案。
【问题讨论】:
-
我认为您真正需要做的就是将较大的 lambda 提取到命名方法中。
-
@JoeC 这真的可能吗?这个 lambda 指的是点击和活动,这意味着我需要在过滤器接受谓词时使用 BiPredicate
-
click -> checkCampaigns(click, campaigns) -
无论基于流的解决方案如何(感知或真实)优雅:我强烈建议使用算法不同的方法。
anyMatch可能看起来很方便,但有 O(n),所以对于m点击和n活动,这是 O(nm)。构建一个Map<ID, Campaign>用作查找会将其更改为 O(n+m)(一些TreeMap可能支持按日期索引,但这可能是第二步) -
顺便说一下,麻烦的
Date类已经被java.time.Instant类取代了。尽可能避免使用Date,但在必须使用旧类中添加的新方法进行转换时:myDate.toInstant()
标签: java java-8 java-stream