Optional.ofNullable 和方法链式调用

56

我对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()获取一些整数值或null。Null可以是以下任何一个表达式:insight.getValues()insight.getValues().get(0)

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



在您的情况下,“insight”为空。最好从不将null传递给方法,而不是在方法内检查null。 - Christoffer Hammarström
3个回答

120

如果您不知道哪些内容可能为null,或者想检查所有内容是否为null,唯一的方法是链接调用Optional.map

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

因此,如果映射器返回null,则会返回一个空的Optional,这允许进行连续调用。

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

对于最终调用orElse(0),如果任何映射返回null,则可以返回默认值0。


4
像这样的东西应该可以运行。
Optional.ofNullable(insight.getValues()).map(vals -> vals.get(0)).map(v -> v.getValue())

根据给定的示例代码,由于#extractFirstValueFrom既不包含@Nullable也不像Guava的checkNotNull()一样检查null,因此假设insight始终为something。因此,将Optional.ofNullable(insight.getValues())包装成Option不会导致NPE。然后组成了一系列转换的调用链(每个结果都是Optional),导致了结果Optional<Integer>,它可能是SomeNone


2
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。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接