#Conclusion
#Conclusion
Conclusion
You cannot do it more concise as you are already doing.
You claim that you do not want .filter(Optional::isPresent) and .map(Optional::get).
This has been resolved by the method @StuartMarks describes, however as a result you now map it to an Optional<T>, so now you need to use .flatMap(this::streamopt) and a get() in the end.
So it still consists of two statements and you can now get exceptions with the new method! Because, what if every optional is empty? Then the findFirst() will return an empty optional and your get() will fail!
So what you have:
things.stream() .map(this::resolve) .filter(Optional::isPresent) .map(Optional::get) .findFirst(); is actually the best way to accomplish what you want, and that is you want to save the result as a T, not as an Optional<T>.
I took the liberty of creating a CustomOptional<T> class that wraps the Optional<T> and provides an extra method, flatStream(). Note that you cannot extend Optional<T>:
class CustomOptional<T> { private final Optional<T> optional; private CustomOptional() { this.optional = Optional.empty(); } private CustomOptional(final T value) { this.optional = Optional.of(value); } private CustomOptional(final Optional<T> optional) { this.optional = optional; } public Optional<T> getOptional() { return optional; } public static <T> CustomOptional<T> empty() { return new CustomOptional<>(); } public static <T> CustomOptional<T> of(final T value) { return new CustomOptional<>(value); } public static <T> CustomOptional<T> ofNullable(final T value) { return (value == null) ? empty() : of(value); } public T get() { return optional.get(); } public boolean isPresent() { return optional.isPresent(); } public void ifPresent(final Consumer<? super T> consumer) { optional.ifPresent(consumer); } public CustomOptional<T> filter(final Predicate<? super T> predicate) { return new CustomOptional<>(optional.filter(predicate)); } public <U> CustomOptional<U> map(final Function<? super T, ? extends U> mapper) { return new CustomOptional<>(optional.map(mapper)); } public <U> CustomOptional<U> flatMap(final Function<? super T, ? extends CustomOptional<U>> mapper) { return new CustomOptional<>(optional.flatMap(mapper.andThen(cu -> cu.getOptional()))); } public T orElse(final T other) { return optional.orElse(other); } public T orElseGet(final Supplier<? extends T> other) { return optional.orElseGet(other); } public <X extends Throwable> T orElseThrow(final Supplier<? extends X> exceptionSuppier) throws X { return optional.orElseThrow(exceptionSuppier); } public Stream<T> flatStream() { if (!optional.isPresent()) { return Stream.empty(); } return Stream.of(get()); } public T getTOrNull() { if (!optional.isPresent()) { return null; } return get(); } @Override public boolean equals(final Object obj) { return optional.equals(obj); } @Override public int hashCode() { return optional.hashCode(); } @Override public String toString() { return optional.toString(); } } You will see that I added flatStream(), as here:
public Stream<T> flatStream() { if (!optional.isPresent()) { return Stream.empty(); } return Stream.of(get()); } Used as:
String result = Stream.of("a", "b", "c", "de", "fg", "hij") .map(this::resolve) .flatMap(CustomOptional::flatStream) .findFirst() .get(); You still will need to return a Stream<T> here, as you cannot return T, because if !optional.isPresent(), then T == null if you declare it such, but then your .flatMap(CustomOptional::flatStream) would attempt to add null to a stream and that is not possible.
As example:
public T getTOrNull() { if (!optional.isPresent()) { return null; } return get(); } Used as:
String result = Stream.of("a", "b", "c", "de", "fg", "hij") .map(this::resolve) .map(CustomOptional::getTOrNull) .findFirst() .get(); Will now throw a NullPointerException inside the stream operations.
#Conclusion
The method you used, is actually the best method.