问题 如何在Java 8中实现Elvis运算符?


我有经典的“Elvis运算符”案例,我在这里调用方法,每个方法都可以返回null并将它们链接在一起:

thing?:nullableMethod1(a)?:nullableMethod2(b)?:nullableMethod3()

在Java 8中,我发现的最忠实的实现是这样的:

return Optional.ofNullable(thing)
    .flatMap(x -> Optional.ofNullable(x.nullableMethod1(a)))
    .flatMap(y -> Optional.ofNullable(y.nullableMethod2(b)))
    .flatMap(z -> Optional.ofNullable(z.nullableMethod3()))

我希望Java的 Optional 有类似于猫王操作员的东西:

public<U> Optional<U> elvisOperator(Function<? super T, ? extends U> mapper) {
    return flatMap(t -> Optional.ofNullable(mapper.apply(t));
}

这样我就不必包装每个返回值:

return Optional.ofNullable(thing)
    .elvisOperator(x -> x.nullableMethod1(a))
    .elvisOperator(y -> y.nullableMethod2(b))
    .elvisOperator(Z::nullableMethod3); // also nice

在Java 8中实现Elvis运算符模式是否有更高效和惯用的方法?


10783
2017-09-12 00:27


起源



答案:


也许我忽略了一些东西,但是有一个你无法使用的理由 Optional#map

以下示例不打印任何内容,如 Optional 是 短路 从某种意义上说,如果里面的价值 Optional 不存在(它是 null 或者 Optional 是空的),它被视为空。

Optional.ofNullable("test")
        .map(s -> null)
        .ifPresent(System.out::println);

出于这个原因,我认为你可以做到以下几点:

return Optional.ofNullable(thing)
               .map(x -> x.nullableMethod1(a))
               .map(y -> y.nullableMethod2(b))
               .map(Z::nullableMethod3);

这会映射你的 thing 如果它存在,或返回空 Optional 除此以外。


12
2017-09-12 00:33



值得指出的是 的文件 Optional.map 表明这种行为是有意的:“如果映射函数返回a null 结果然后此方法返回一个空 Optional”。 - Holger
@Holger,和 这个 从长远来看,这解释了为什么这是一个坏主意。或者,至少是次优的(从FP角度来看)。 - melston


答案:


也许我忽略了一些东西,但是有一个你无法使用的理由 Optional#map

以下示例不打印任何内容,如 Optional 是 短路 从某种意义上说,如果里面的价值 Optional 不存在(它是 null 或者 Optional 是空的),它被视为空。

Optional.ofNullable("test")
        .map(s -> null)
        .ifPresent(System.out::println);

出于这个原因,我认为你可以做到以下几点:

return Optional.ofNullable(thing)
               .map(x -> x.nullableMethod1(a))
               .map(y -> y.nullableMethod2(b))
               .map(Z::nullableMethod3);

这会映射你的 thing 如果它存在,或返回空 Optional 除此以外。


12
2017-09-12 00:33



值得指出的是 的文件 Optional.map 表明这种行为是有意的:“如果映射函数返回a null 结果然后此方法返回一个空 Optional”。 - Holger
@Holger,和 这个 从长远来看,这解释了为什么这是一个坏主意。或者,至少是次优的(从FP角度来看)。 - melston