Optional.ofNullable 和方法链接

Optional.ofNullable and method chaining

我对Optional.ofNullable方法感到惊讶。有一天我写了一个函数,它应该 return 一个 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 可以是以下表达式中的每一个:insight.getValues()insight.getValues().get(0).

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

像这样应该行得通

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.

如果您不知道 null 是什么,或者想检查 null 的所有内容,唯一的方法是将调用链接到 Optional.map:

If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result. Otherwise return an empty Optional.

因此,如果映射器 return null,一个空的 Optional 将被 returned,这允许链式调用。

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

orElse(0) 的最终调用允许 return 默认值 0 如果任何映射器 returned null.

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 作为 null 安全操作。 java.util.Optional#map 类似地使用了 ifPresent Api。