有两个类和两个对应的列表:
class Click { long campaignId; Date date; } class Campaign { long campaignId; Date start; Date end; String type; } List<Click> clicks = ..; List<Campaign> campaigns = ..;
而要查找所有Click以s clicks说:
Click
clicks
有一个对应Campaign的campaigns列表,即,Campaign具有相同的campaignIdAND
Campaign
campaigns
campaignId
这Campaign具有type“预期”且
type
这Campaigns.start< click.date<Campaigns.end
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());
我想知道是否有更简单的解决方案。
突出的一件事是您的第二个要求与匹配无关,这只是一个条件campaigns。您必须测试这是否对您更好:
clicks.stream() .filter(click -> campaigns.stream() .filter(camp -> "prospecting".equals(camp.type)) .anyMatch(camp -> camp.campaignId == click.campaignId && camp.end.after(click.date) && camp.start.before(click.date) ) ) .collect(Collectors.toList());
否则,我从未见过不涉及在第一个谓词内部流式传输第二个集合的流解决方案,因此您做不到的事不会比您做的更好。在可读性方面,如果您感到困惑,则创建一个测试布尔条件的方法并调用它:
clicks.stream() .filter(click -> campaigns.stream() .filter(camp -> "pre".equals(camp.type)) .anyMatch(camp -> accept(camp, click)) ) .collect(Collectors.toList()); static boolean accept(Campaign camp, Click click) { return camp.campaignId == click.campaignId && camp.end.after(click.date) && camp.start.before(click.date); }
最后,有2条无关的建议:
Date
enum
String