java Optional.ofNullable 和方法链

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35337020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 00:01:21  来源:igfitidea点击:

Optional.ofNullable and method chaining

javajava-8optional

提问by sebast26

I was surprised by Optional.ofNullablemethod. Some day I wrote a function that supposed to return an Optional:

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

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

I mistakenly thought that Optional.ofNullablewill prevent any NullPointerExceptionsinside of argument expression.

我错误地认为这Optional.ofNullable会阻止任何NullPointerExceptions内部的参数表达。

Now I think I know that it was very foolish idea. Java have to resolve arguments first to pass it to Optional.ofNullableinvocation.

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

But I have a question. Is there a nice and good way to accomplish my goal? I would like to obtain from expression insight.getValues().get(0).getValue()some Integer value or null. Null can be each one of the expressions: insight.getValues()or insight.getValues().get(0).

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

I know that I can just put this in try/catch block but I am wondering if there is more elegant solution.

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

回答by Tunaki

If you have no idea what can be null, or want to check everything for null, the only way is to chain calls to Optional.map:

如果您不知道可以是什么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.

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

As such, if the mapper return null, an empty Optionalwill be returned, which allows to chain calls.

因此,如果映射器返回nullOptional将返回一个空值,这允许链接调用。

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

The final call to orElse(0)allows to return the default value 0 if any mapper returned null.

orElse(0)如果任何映射器返回,则最后一次调用允许返回默认值 0 null

回答by hahn

smth like this should work

像这样应该可以工作

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

well, according to the sample code given, as #extractFirstValueFromdo not contain neither @Nullablenor checks for null like Guava's checkNotNull(), let's assume that insightis always something. thus wrapping Optional.ofNullable(insight.getValues())into Optionwould not result with NPE. then call chain of transformations is composed (each results with Optional) that lead to result Optional<Integer>that might be either Someor None.

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

回答by Kesa_Wu

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();
}

I think sometiems you could use ifPresentApi as a null-safe operation. the java.util.Optional#mapused ifPresentApi similarly.

我认为有时您可以将ifPresentApi 用作空安全操作。所述java.util.Optional#map用过的ifPresent阿比类似。