Question: I'd like to convert the following code, which breaks from the outer loop, into Java 8 `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;
}

```

Answer: 
Every answer here uses `flatMap`, which until java-10 [is not lazy](https://stackoverflow.com/questions/46288915/is-flatmap-guaranteed-to-be-lazy). In your case that would mean that `alertActions` is traversed entirely, while in the for loop example - not. Here is a simplified example:

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

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

    public List<String> getNickNames() {
        return nickNames;
    }
}

```

And some usage:

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

```

In `java-8` this will print *both* `one` and `uno`, since `flatMap` is not lazy.

On the other hand in `java-10` this will print `one` - and this is what you care about if you want to have your example translated to `stream-based` 1 to 1.
Try this out,

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

```