仅当 Optional 存在时才解包

Unwrap an Optional only if it is present

所以目前我有

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) 方法,其中 returns 一个 Optional<PageDetail>,我想将字符串 displayNamedescription 设置为PageDetail 对象字段的值(如果存在)。否则,我想将它设置为一些默认值。

我的问题是,有没有更好的方法来重写它?我目前的代码似乎有点冗长乏味,我想知道是否有更简洁的方法来做到这一点。

使用Optional#orElseGet that takes a 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 仅当 Optional 具有 null 值时才会创建一个空的 PageDetail。这使您的代码资源高效。

Editable/compilable 示例:https://ideone.com/9h1Ntg

编辑:感谢大家的反馈!我实际上添加了 orElseGet,我发现它更好。我还修复了解包 Optional 的代码,因此 pageDetail 最终成为一个实际的 PageDetail 实例。

编辑 2: 添加了不同的语法示例和 editable/compilable 示例。

你可以这样写:

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 is not set, map will return the same unset Optional. Otherwise, it will map it to an Optional containing the result of getName(). Then we can use orElse 为 return 默认值,当 Optional 未设置时。