且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java 8流:从一个列表中查找与根据另一列表中的值计算得出的条件相匹配的项目

更新时间:2022-05-05 23:03:49

一件突出的事情是您的第二个要求与匹配无关,这仅是campaigns的条件.您必须测试这是否对您更好:

One thing that stands out is that your 2nd requirement has nothing to do with the matching, it's a condition on campaigns only. You'd have to test if this is any better for you:

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());

否则,我从未见过不涉及在第一个谓词内部流式传输第二个集合的流解决方案,因此您做不到的事情不会比您做的更好.在可读性方面,如果您感到困惑,则创建一个测试布尔条件的方法并调用它:

Otherwise, I have never seen a streams solution which does not involve streaming the 2nd collection inside the predicate of the 1st, so you can't do much better than what you did. In terms of readability, if it looks that confusing to you then create a method that test for the boolean condition and call it:

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个不相关的建议:

Finally, 2 unrelated suggestions:

  1. 不要使用旧的Date类,而应使用新的本地日期.
  2. 如果Campaigntype仅具有一些预定义的值(例如已提交",潜在",已接受..."),则enum比一般的String更合适>.
  1. Don't use the old Date class, instead use the new java.time API's LocalDate.
  2. If Campaign's type can only have some predefined values (like "submitted", "prospecting", "accepted"...) then an enum would be a better fit than a general String.