【问题标题】:Java 8 Streams - Filter More Than One ConditionJava 8 Streams - 过滤多个条件
【发布时间】:2018-08-28 07:52:59
【问题描述】:
根据一些运动结果数据,我有一个Fixture 对象,它有getHome() 和getAway() 方法。我想缩短我写的这个方法,只使用一个 lambda 函数(而不是创建一个新列表和两个 lambdas),这可能吗?
private Collection<FixtureResult> finalResults(Team team) {
List<FixtureResult>finalResults = new ArrayList<>();
List<FixtureResult> homeResults = resultList.stream().filter(fixture ->
fixture.getHome().equals(team))
.collect(toList());
List<FixtureResult> awayResults = resultList.stream().filter(fixture ->
fixture.getAway().equals(team))
.collect(toList());
finalResults.addAll(homeResults);
finalResults.addAll(awayResults);
return finalResults;
}
【问题讨论】:
标签:
java
lambda
java-8
java-stream
【解决方案1】:
如果你想看中 lambda:
Predicate<FixtureResult> isHome = fr -> fr.getHome().equals(team)
Predicate<FixtureResult> isAway = fr -> fr.getAway().equals(team)
resultList.stream()
.filter(isHome.or(isAway))
.collect(toList()));
您甚至可以提取 compose 谓词以单独测试它,而不涉及流,这对于更复杂的谓词很有用:
Predicate<FixtureResult> isHomeOrAway = isHome.or(isAway)
assertTrue(isHomeOrAway(homeFixture));
...
【解决方案2】:
您可以执行以下操作
someStream.filter(((Predicate<SomeClass>) someObject-> someCondition).or(someObject-> someOtherCondition))
或者您可以定义自己的“或”函数,不会导致如此深的层次结构
@SuppressWarnings("unchecked")
<R> Predicate<R> or(Predicate<R> ...predicates) {
return r -> Arrays.stream(predicates).anyMatch(p -> p.test(r));
}
这为您提供了一个更干净的界面,无需强制转换和嵌套
.filter(or(
yourObject -> {
return false;
},
yourObject -> {
return false;
},
yourObject -> {
return false;
},
yourObject -> {
return false;
}
))
【解决方案3】:
您可以简单地创建条件连接或可以连接多个过滤器调用
条件串联
myList.stream()
.filter(element -> (condition1 && condition2 && condition3))
多重过滤调用
myList.stream()
.filter(element -> condition1)
.filter(element -> condition2)
.filter(element -> condition3)
【解决方案4】:
够简单
resultList.stream()
.filter(fixture -> fixture.getHome().equals(team) || fixture.getAway().equals(team)))
.collect(toList());
编辑:这是假设顺序对您无关紧要。如果您的最终名单需要有主场结果然后离开,请查看Elliott Frisch's answer。
【解决方案5】:
假设顺序无关紧要,您可以在一行中完成。喜欢,
private Collection<FixtureResult> finalResults(Team team) {
return resultList.stream()
.filter(fixture -> fixture.getHome().equals(team)
|| fixture.getAway().equals(team))
.collect(toList());
}
如果订单很重要(主场结果然后离开),您可以用一个 List 点赞来完成
private Collection<FixtureResult> finalResults(Team team) {
List<FixtureResult> al = new ArrayList<>(resultList.stream()
.filter(fixture -> fixture.getHome().equals(team)).collect(toList()));
al.addAll(resultList.stream()
.filter(fixture -> fixture.getAway().equals(team)).collect(toList()));
return al;
}