Distinguish empty Stream, Stream of empty Optionals only, Stream with at least one non-empty Optional

74 Views Asked by At

I have a Stream<Optional<T>>.

I want to use the findFirst()/findAny() methods to return a value. However I want to throw different exceptions depending on the Stream being empty or not.

Stream<Optional<MyType>> stream = ...;
return stream
  .flatMap(Optional::stream)
  .findFirst()
  .orElseThrow(() -> {
    // I want to know here if the stream was empty or not but flatMap forgot that
});

The logic should still be lazily evaluated, once I found a non-empty Optional, the stream should not be further progressed and the value should be returned early.

I tried to mutate a variable in the upper scope in a map to read from it but variables used in Lambda expressions have to be final.

boolean empty = true;
Stream<Optional<MyType>> stream = ...;
return stream
  .map(t -> {
    empty = false; //error, must be final
    return t;
  })
  .flatMap(Optional::stream)
  .findFirst()
  .orElseThrow(() -> {
    if (empty) {
      throw ...;
    } else {
      throw ...;
    }
});

I tried to write a plain for loop but this does not work with streams:

boolean empty = true;
Stream<Optional<MyType>> stream = ...;
for (Optional<MyType> o: stream) { //error, can't for loop on type Stream<...>
  if (o.isEmpty()) {
    empty = false;
  } else {
    return o.get();
  }
}
if (empty) {
  throw ...;
} else {
  throw ...;
}

What can I do here?

0

There are 0 best solutions below