Java 转换为流

Java 转换为流,java,java-8,java-stream,Java,Java 8,Java Stream,我想将以下代码转换成Java8Streams,这段代码从外部循环中断 private CPBTuple getTuple(Collection<ConsignmentAlert> alertsOnCpdDay) { CPBTuple cpbTuple=null; OUTER: for (ConsignmentAlert consignmentAlert : alertsOnCpdDay) { List<AlertAction>

我想将以下代码转换成Java8
Stream
s,这段代码从外部循环中断

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;
}
private CPBTuple getTuple(收集警报soncpdday)
{
CPBTuple CPBTuple=null;
外部:
对于(委托警报委托警报:警报SONCPDDAY){
List alertActions=CommissionAlert.getAlertActions();
用于(AlertAction AlertAction:alertActions){
cpbTuple=handleAlertAction(reportDTO、委托ID、alertAction);
if(cpbTuple.isPresent()){
打破外部;
}
}
}
返回cpb双倍;
}

由于您在第一次匹配时中断了循环,因此可以使用flatMap流消除循环,该流返回第一个可用匹配:

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);
}
private CPBTuple getTuple(收集警报soncpdday){
返回alertsOnCpdDay.stream()
.flatMap(ca->ca.getAlertActions().stream())
.map(aa->handleAlertAction(reportDTO,CommissionId,aa))
.filter(CPBTuple::isPresent)
.findFirst()
.orElse(空);
}

这样的东西就足够了:

return alertsOnCpdDay.stream()
              .flatMap(s-> s.getAlertActions().stream())
              .map(s-> handleAlertAction(reportDTO, consignmentId, s))
              .filter(s-> s.isPresent())
              .findFirst().orElse(null);
也就是说,更好的选择是将方法返回类型更改为
Optional
,然后只返回
findFirst()的结果。e、 g

private Optional<CPBTuple> getTuple(Collection<ConsignmentAlert> alertsOnCpdDay) {
    return alertsOnCpdDay.stream()
                  .flatMap(s-> s.getAlertActions().stream())
                  .map(s-> handleAlertAction(reportDTO, consignmentId, s))
                  .filter(s-> s.isPresent())
                  .findFirst();
}
private可选getTuple(收集警报soncpdday){
返回alertsOnCpdDay.stream()
.flatMap(s->s.getAlertActions().stream())
.map(s->handleAlertAction(reportDTO,CommissionId,s))
.filter(s->s.isPresent())
.findFirst();
}
这更好,因为它可以更好地记录方法,并有助于防止在处理空值时出现问题。

尝试一下

alertsOnCpdDay.stream()
    .map(ConsignmentAlert::getAlertActions)
    .flatMap(List::stream)
    .map(alertAction -> handleAlertAction(reportDTO, consignmentId, alertAction))
    .filter(CPBTuple::isPresent)
    .findFirst().orElse(null);

这里的每个答案都使用
flatMap
,直到java-10。在您的例子中,这意味着
alertActions
是完全遍历的,而在for循环中则是不遍历的。以下是一个简化的示例:

static class User {
    private final List<String> nickNames;

    public User(List<String> nickNames) {
        this.nickNames = nickNames;
    }

    public List<String> getNickNames() {
        return nickNames;
    }
}
java-8
中,这将同时打印
one
uno
,因为
flatMap
并不懒惰


另一方面,在
java-10
中,这将打印
one
——如果您希望将示例转换为基于流的
1到1,这就是您关心的问题。

.map(s->handleAlertAction(reportDTO,commissionId,s)),这不会对流中的所有元素进行计算?@Pushparaj nope,它会在找到第一个警报后立即停止,就像您所展示的代码一样。我认为,这是我对流的错误理解,请纠正我,我认为所有警报都会直接映射到getAlertActions,然后映射,并根据条件对其进行筛选,然后返回第一个匹配的警报。因此,我们在每个AlertAction执行handleAlertAction(reportDTO,CommissionId,s)方法。我建议您在流调用链中的每个点之前放置一个换行符。我已根据您的请求进行了更改。很好,我能够在JDK8上测试这一点,尽管我仍然在JDK9 atm上,因此我无法在JDK10上进行验证,但我相信您:)+1.@Aominè实际上这是我们升级到jdk-10的要点之一,这对于从循环转换某些代码非常重要。。。
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();
}