Guava's Optional pattern is great, as it helps remove the ambiguity with null. The transform method is very helpful for creating null-safe method chains when the first part of the chain may be absent, but isn't useful when other parts of the chain are absent.
This question is related to Guava Optional type, when transformation returns another Optional, which asks essentially the same question but for a different use case which I think may not be the intended use of Optional (handling errors).
Consider a method Optional<Book> findBook(String id). findBook(id).transform(Book.getName) works as expected. If there is no book found we get an Absent<String>, if there is a book found we get Present<String>.
In the common case where intermediate methods may return null/absent(), there does not seem to be an elegant way to chain the calls. For example, assume that Book has a method Optional<Publisher> getPublisher(), and we would like to get all the books published by the publisher of a book. The natural syntax would seem to be findBook(id).transform(Book.getPublisher).transform(Publisher.getPublishedBooks), however this will fail because the transform(Publisher.getPublishedBooks) call will actually return an Optional<Optional<Publisher>>.
It seems fairly reasonable to have a transform()-like method on Optional that would accept a function which returns an Optional. It would act exactly like the current implementation except that it simply would not wrap the result of the function in an Optional. The implementation (for Present) might read:
public abstract <V> Optional<V> optionalTransform(Function<? super T, Optional<V>> function) {
return function.apply(reference);
}
The implementation for Absent is unchanged from transform:
public abstract <V> Optional<V> optionalTransform(Function<? super T, Optional<V>> function) {
checkNotNull(function);
return Optional.absent();
}
It would also be nice if there were a way to handle methods that return null as opposed to Optional for working with legacy objects. Such a method would be like transform but simply call Optional.fromNullable on the result of the function.
I'm curious if anyone else has run into this annoyance and found nice workarounds (which don't involve writing your own Optional class). I'd also love to hear from the Guava team or be pointed to discussions related to the issue (I didn't find any in my searching).