Java 8 随着地图的发展携带参数的可选扩展

jua*_*nmf 1 java option-type

已经提出了几种情况,其中使用可选保留对先前映射对象的引用会很酷。

    // Normally the following is a good candidate for Optional fluent API (imagine also all the null checks that could be necessary)

    A a = new A();
    B b = calculateB(a);
    C c = calculateC(b)
    D d = calculateD(c)
    E e = calculateE(d)

    // As 
    E e = Optional.ofNullable(a)
            .map(this::calculateB)
    ...
    
    // But the following can't be expressed with Optional API
        A a = new A();
    B b = calculateB(a);
    C c = calculateC(a, b)
    D d = calculateD(a, c)
    E e = calculateE(a, d)

    // Something like the following sounds tempting
    PowerOptional.ofNullable(a)
            .mapAndKeep(this::calculateB) // mapAndKeep would carry the input as well to next call.
            .map((a, b) -> calculateC(a, b))
            .map((a, c) -> calculateD(a, c))
            .map((a, d) -> calculateE(a, d))
            .orElse(null);
    
Run Code Online (Sandbox Code Playgroud)

这可以提高相当麻烦的方法的可读性。有没有一个库可以解决这个问题?想法(也关于命名)?

And*_*kin 5

这只是flatMap方法。它可用于对返回Optionals 的多个操作进行排序,并且允许您将中间结果绑定到变量。在你的情况下,它会是这样的

Optional.ofNullable(nullableA)
  .flatMap(a -> calculateB(a)
    .flatMap(b -> calculateC(a, b)
      .flatMap(c -> calculateD(a, c)
        .flatMap(d -> calculateE(a, d)))))
  .orElse(null)
Run Code Online (Sandbox Code Playgroud)

请注意,不仅a,而且实际上所有中间结果都可以在后面的计算步骤中使用。在极端情况下,它可能看起来像这样:

Optional.ofNullable(nullableA)
  .flatMap(a -> calculateB(a)
    .flatMap(b -> calculateC(a, b)
      .flatMap(c -> calculateD(a, b, c)
        .flatMap(d -> calculateE(a, b, c, d)))))
  .orElse(null)
Run Code Online (Sandbox Code Playgroud)

即每一步都可能取决于所有先前步骤的中间结果。

Afaik,截至 2022 年,Java 中没有特殊的语法。避免增加缩进(在 Haskell 中流行)的标准解决方案是某种do/ for-yield- 语法,例如在 Scala 中,它可以垂直编写,并且类似于通常的命令式语法:

for
  a <- ofNullable(aNullable)
  b <- calculateB(a)
  c <- calculateC(a, b)
  d <- calculateD(a, c)
  e <- calculateE(a, d)
yield e
Run Code Online (Sandbox Code Playgroud)