Optional.ofNullable和方法链

时间:2016-02-11 10:40:24

标签: java java-8 optional

我对Optional.ofNullable方法感到惊讶。有一天我写了一个应该返回Optional的函数:

private Optional<Integer> extractFirstValueFrom(InsightsResponse insight) {
    return Optional.ofNullable(insight.getValues().get(0).getValue());
}

我错误地认为Optional.ofNullable会阻止参数表达式中的任何NullPointerExceptions

现在我想我知道这是非常愚蠢的想法。 Java必须首先解析参数以将其传递给Optional.ofNullable调用。

但我有一个问题。有没有一个很好的方法来实现我的目标?我想从表达式insight.getValues().get(0).getValue()获得一些Integer值或null。 Null可以是表达式中的每一个:insight.getValues()insight.getValues().get(0)

我知道我可以把它放在try / catch块中,但我想知道是否有更优雅的解决方案。

3 个答案:

答案 0 :(得分:39)

如果你不知道null可以是什么,或者想要检查null的所有内容,唯一的方法是将来电链接到Optional.map

  

如果存在值,则将提供的映射函数应用于该值,如果结果为非null,则返回描述结果的Optional。否则返回一个空的Optional。

因此,如果映射器返回null,将返回空的Optional,这允许链接调用。

Optional.ofNullable(insight)
        .map(i -> i.getValues())
        .map(values -> values.get(0))
        .map(v -> v.getValue())
        .orElse(0);

orElse(0)的最终调用允许在任何mapper返回null时返回默认值0.

答案 1 :(得分:2)

像这样的人应该工作

Optional.ofNullable(insight.getValues()).map(vals -> vals.get(0)).map(v -> v.getValue())

好吧,根据给出的示例代码,由于#extractFirstValueFrom不包含@Nullable,也不像Guava&#39; s checkNotNull()那样检查null,我们假设insight始终为something。因此将Optional.ofNullable(insight.getValues())包裹到Option不会导致NPE。然后组成调用链转换(每个结果都带有Optional),导致结果Optional<Integer>可能是SomeNone

答案 2 :(得分:0)

public Optional<Integer> extractFirstValueFrom(InsightsResponse insight) {
    AtomicReference<Optional<Integer>> result = new AtomicReference<>(Optional.empty());
    Optional.ofNullable(insight.getValues().get(0)).ifPresent(ele -> result.set(Optional.ofNullable(ele.getValue())));
    return result.get();
}

我认为您可以使用ifPresent Api作为空安全操作。 java.util.Optional#map同样使用了ifPresent Api。