我希望将以下代码从外部循环转换为Java 8 Stream
。
private CPBTuple getTuple(Collection<ConsignmentAlert> alertsOnCpdDay)
{
CPBTuple cpbTuple=null;
OUTER:
for (ConsignmentAlert consignmentAlert : alertsOnCpdDay) {
List<AlertAction> alertActions = consignmentAlert.getAlertActions();
for (AlertAction alertAction : alertActions) {
cpbTuple = handleAlertAction(reportDTO, consignmentId, alertAction);
if (cpbTuple.isPresent()) {
break OUTER;
}
}
}
return cpbTuple;
}
答案 0 :(得分:4)
此处的每个答案都使用flatMap
,直到java-10 is not lazy。在你的情况下,这意味着alertActions
完全遍历,而在for循环示例中 - 不是。这是一个简化的例子:
static class User {
private final List<String> nickNames;
public User(List<String> nickNames) {
this.nickNames = nickNames;
}
public List<String> getNickNames() {
return nickNames;
}
}
还有一些用法:
public static void main(String[] args) {
Arrays.asList(new User(Arrays.asList("one", "uno")))
.stream()
.flatMap(x -> x.getNickNames().stream())
.peek(System.out::println)
.filter(x -> x.equalsIgnoreCase("one"))
.findFirst()
.get();
}
在java-8
中,这将打印 one
和uno
,因为flatMap
并非懒惰。
另一方面,在java-10
中,这将打印one
- 如果您希望将示例翻译为stream-based
1到1,这就是您所关心的。
答案 1 :(得分:2)
有些事情就足够了:
1
也就是说,更好的选择是将方法返回类型更改为return alertsOnCpdDay.stream()
.flatMap(s-> s.getAlertActions().stream())
.map(s-> handleAlertAction(reportDTO, consignmentId, s))
.filter(s-> s.isPresent())
.findFirst().orElse(null);
,然后只返回Optional<CPBTuple>
的结果。 e.g。
findFirst()
这样做更好,因为它更好地记录了该方法,并有助于防止在处理无效时出现的问题。
答案 2 :(得分:1)
由于你在第一次匹配时突破了循环,你可以使用带有flatMap的Stream消除循环,它返回第一个可用的匹配:
private CPBTuple getTuple(Collection<ConsignmentAlert> alertsOnCpdDay) {
return alertsOnCpdDay.stream()
.flatMap(ca -> ca.getAlertActions().stream())
.map(aa -> handleAlertAction(reportDTO, consignmentId, aa))
.filter(CPBTuple::isPresent)
.findFirst()
.orElse(null);
}
答案 3 :(得分:1)
试试这个,
alertsOnCpdDay.stream()
.map(ConsignmentAlert::getAlertActions)
.flatMap(List::stream)
.map(alertAction -> handleAlertAction(reportDTO, consignmentId, alertAction))
.filter(CPBTuple::isPresent)
.findFirst().orElse(null);