转换为流

时间:2018-06-07 08:40:13

标签: java java-8 java-stream

我希望将以下代码从外部循环转换为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;
}

4 个答案:

答案 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中,这将打印 oneuno,因为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);