Ответ 1
Вы можете использовать этот синтаксис:
ofNullable(key)
.map(Person::get)
.map(x -> {printName(x);return x;})
.map(x -> {printAddress(x);return x;});
Я хочу использовать свободный api Optional
и применить к нему два Consumer
.
Мне снится что-то вроде этого:
Optional.ofNullable(key)
.map(Person::get)
.ifPresent(this::printName)
.ifPresent(this::printAddress); // not compiling, because ifPresent is void
Как применить несколько Consumer
к Optional
?
Вы можете использовать этот синтаксис:
ofNullable(key)
.map(Person::get)
.map(x -> {printName(x);return x;})
.map(x -> {printAddress(x);return x;});
Хотя это может показаться не очень элегантным, я бы просто объединил оба метода в одну lambda
и передал это ifPresent
:
ofNullable(key)
.map(Person::get)
.ifPresent(x -> {printName(x); printAddress(x);});
В качестве альтернативы вы также можете использовать andThen
для andThen
нескольких потребителей, хотя для этого вам потребуется указать ссылку на метод Consumer
, которая также не очень элегантна.
ofNullable(key)
.map(Person::get)
.ifPresent(((Consumer) this::printName).andThen(this::printAddress));
Здесь, как вы можете реализовать отсутствующий метод peek
для параметра Optional
:
<T> UnaryOperator<T> peek(Consumer<T> c) {
return x -> {
c.accept(x);
return x;
};
}
Использование:
Optional.ofNullable(key)
.map(Person::get)
.map(peek(this::printName))
.map(peek(this::printAddress));
Возможно, что-то вроде этого:
Optional.ofNullable(key)
.map(Person::get)
.ifPresent(combine(this::printAddress, this::printWish));
где combine
:
public <T> Consumer<T> combine(Consumer<T>... cs) {
return x -> Stream.of(cs).peek(c -> c.accept(x)).close();
}
С новым потоковым методом в Дополнительном API, начиная с JDK9, вы можете вызвать stream
метод для преобразования из Optional<T>
в Stream<T>
которое затем позволяет peek
а затем, если вы хотите вернуться к Optional<T>
просто вызовите findFirst()
или findAny()
.
пример в вашем случае:
Optional.ofNullable(key)
.map(Person::get) // Optional<Person>
.stream() // Stream<Person>
.peek(this::printName)
.peek(this::printAddress)
...
Альтернатива Java 8 (map
+ orElseGet
):
Optional.ofNullable(key)
.map(Person::get) // Optional<Person>
.map(Stream::of) // Optional<Stream<Person>>
.orElseGet(Stream::empty) // Stream<Person>
.peek(this::printName)
.peek(this::printAddress)
.findAny();