Unwrap a Необязательно, только если он присутствует

Итак, в настоящее время у меня

String uri = website.getUri();
Optional<PageDetail> pageDetail = webClient.getDetailOfUri(uri);
String displayName;
String description;
if (pageDetail.isPresent()) {
    displayName = pageDetail.get().getName();
    description = pageDetail.get().getDescription();
} else {
    displayName = uri;
    description = "";
}

Я вызываю метод getDetailOfUri(uri), который возвращает Optional<PageDetail>, и я хотел бы установить строки displayName и description значения полей объекта PageDetail, если они есть. В противном случае, я хотел бы установить его для некоторых значений по умолчанию.

Мой вопрос в том, есть ли лучший способ переписать это? Мой текущий код кажется немного длинным и утомительным, и я хотел бы знать, есть ли более сжатый способ сделать это.

Ответ 1

Вы можете написать:

String uri = website.getUri();
Optional<PageDetail> pageDetail = webClient.getDetailOfUri(uri);
String displayName = pageDetail.map(PageDetail::getName).orElse(uri);
String description = pageDetail.map(PageDetail::getDescription).orElse("");

Если Optional не задано, map вернет тот же unset Optional. В противном случае он сопоставит его с Optional, содержащим результат getName(). Затем мы можем использовать orElse, чтобы вернуть значение по умолчанию, когда параметр Optional не установлен.

Ответ 2

Используйте Необязательный # orElseGet, который принимает Supplier:

// Reference to the constructor, but you could use a Factory, etc.
// All you need is a method that returns a PageDetail
// See the Javadoc and http://www.byteslounge.com/tutorials/java-8-consumer-and-supplier
Supplier<PageDetail> emptySupplier = PageDetail::new;

pageDetail = pageDetail.orElseGet(emptySupplier);
// works the same
//pageDetail = pageDetail.orElseGet(() -> new PageDetail());

String displayname = pageDetail.getName();
String uri = pageDetail.getUri();

orElseGet создаст пустой PageDetail только в том случае, если опция имеет нулевое значение. Это позволяет эффективно использовать ваш ресурс кода.

Редактируемый/компилируемый пример: https://ideone.com/9h1Ntg

Изменить: Спасибо всем за отзыв! Я действительно добавлял orElseGet, который мне нахожу лучше. Я также исправил код, чтобы развернуть Optional, поэтому pageDetail заканчивается фактическим экземпляром pageDetail.

Изменить 2: Добавлен другой пример синтаксиса и редактируемый/компилируемый пример.