I want to use the fluent api of Optional
and apply two Consumer
s to it.
I'm dreaming about something like this:
Optional.ofNullable(key)
.map(Person::get)
.ifPresent(this::printName)
.ifPresent(this::printAddress); // not compiling, because ifPresent is void
How do I apply several Consumer
s to an Optional
?
peek() method in Java is used to retrieve or fetch the first element of the Stack or the element present at the top of the Stack. The element retrieved does not get deleted or removed from the Stack. Parameters: The method does not take any parameters.
Java Stream peek() method returns a new Stream consisting of all the elements from the original Stream after applying a given Consumer action. Note that the peek() method is an intermediate Stream operation so, to process the Stream elements through peek() , we must use a terminal operation.
Optional isn't magic, it's an object like any other, and the Optional reference itself can be null. It's the contents of the Optional that can't be null.
The filter() method of java. util. Optional class in Java is used to filter the value of this Optional instance by matching it with the given Predicate, and then return the filtered Optional instance. If there is no value present in this Optional instance, then this method returns an empty Optional instance.
Here's how you can implement the missing peek
method for Optional
:
<T> UnaryOperator<T> peek(Consumer<T> c) {
return x -> {
c.accept(x);
return x;
};
}
Usage:
Optional.ofNullable(key)
.map(Person::get)
.map(peek(this::printName))
.map(peek(this::printAddress));
You can use this syntax:
ofNullable(key)
.map(Person::get)
.map(x -> {printName(x);return x;})
.map(x -> {printAddress(x);return x;});
With the new stream method in the Optional API as of JDK9, you can invoke the stream
method to transform from Optional<T>
to Stream<T>
which then enables one to peek
and then if you want to go back to the Optional<T>
just invoke findFirst()
or findAny()
.
an example in your case:
Optional.ofNullable(key)
.map(Person::get) // Optional<Person>
.stream() // Stream<Person>
.peek(this::printName)
.peek(this::printAddress)
...
While this may not seem very elegant, I would just combine both methods into one lambda
and pass that to ifPresent
:
ofNullable(key)
.map(Person::get)
.ifPresent(x -> {printName(x); printAddress(x);});
Alternatively, you could also use andThen
to chain multiple consumers, although this would require you to cast the method reference to Consumer
, which is not very elegant either.
ofNullable(key)
.map(Person::get)
.ifPresent(((Consumer) this::printName).andThen(this::printAddress));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With