Гуава Optional
шаблон отличный, поскольку он помогает устранить двусмысленность с нулевым значением. Метод transform
очень полезен для создания нулеустойчивых цепочек методов, когда первая часть цепочки может отсутствовать, но не полезна, когда другие части цепи отсутствуют.
Этот вопрос связан с Guava Необязательный тип, когда преобразование возвращает другой Необязательный, который задает практически тот же вопрос, но для другого варианта использования, который, я думаю, может не быть предполагаемое использование Optional
(ошибки обработки).
Рассмотрим метод Optional<Book> findBook(String id)
. findBook(id).transform(Book.getName)
работает так, как ожидалось. Если нет книги, мы получаем Absent<String>
, если есть найденная книга, мы получаем Present<String>
.
В общем случае, когда промежуточные методы могут возвращать null
/absent()
, кажется, нет элегантного способа цепной связи. Например, предположим, что Book
имеет метод Optional<Publisher> getPublisher()
, и мы хотели бы получить все книги, изданные издателем книги. Естественный синтаксис будет выглядеть как findBook(id).transform(Book.getPublisher).transform(Publisher.getPublishedBooks)
, однако это не сработает, потому что вызов transform(Publisher.getPublishedBooks)
действительно вернет Optional<Optional<Publisher>>
.
Кажется довольно разумным иметь transform()
-подобный метод на Optional
, который будет принимать функцию, которая возвращает Optional
. Он будет действовать точно так же, как и текущая реализация, за исключением того, что он просто не будет обертывать результат функции в Необязательном. Реализация (для Present
) может читать:
public abstract <V> Optional<V> optionalTransform(Function<? super T, Optional<V>> function) {
return function.apply(reference);
}
Реализация для Absent
не изменяется от transform
:
public abstract <V> Optional<V> optionalTransform(Function<? super T, Optional<V>> function) {
checkNotNull(function);
return Optional.absent();
}
Было бы неплохо, если бы был способ обработать методы, возвращающие null
, а не Optional
для работы с устаревшими объектами. Такой метод будет похож на transform
, а просто вызовет Optional.fromNullable
на результат функции.
Мне любопытно, если кто-то еще столкнулся с этим досадой и нашел хорошие обходные пути (которые не связаны с написанием собственного класса Optional
). Я также хотел бы услышать от команды Гуавы или указать на дискуссии, связанные с проблемой (я не нашел их в поиске).