有两个类和两个对应的列表:
class Click {
long campaignId;
Date date;
}
class Campaign {
long campaignId;
Date start;
Date end;
String type;
}
List<Click> clicks = ..;
List<Campaign> campaigns = ..;
并希望在 clicks
中找到所有 Click
:
在
campaigns
列表中有相应的Campaign
,即Campaign
具有相同的campaignId
并且此
Activity
有type
= "prospective"AND此
Campaigns.start
<click.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());
我想知道是否有更简单的解决方案。
最佳答案
好吧,IMO 有一种非常巧妙的方法可以解决您的问题,这是 Holger 的原创想法(我会找到问题并将其链接到此处)。
您可以定义执行检查的方法(我稍微简化了它):
static boolean checkClick(List<Campaign> campaigns, Click click) {
return campaigns.stream().anyMatch(camp -> camp.getCampaignId()
== click.getCampaignId());
}
并定义一个绑定(bind)参数的函数:
public static <T, U> Predicate<U> bind(BiFunction<T, U, Boolean> f, T t) {
return u -> f.apply(t, u);
}
用法是:
BiFunction<List<Campaign>, Click, Boolean> biFunction = YourClass::checkClick;
Predicate<Click> predicate = bind(biFunction, campaigns);
clicks.stream()
.filter(predicate::test)
.collect(Collectors.toList());
关于Java 8 流 : find items from one list that match conditions calculated based on values from another list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45397570/