【问题标题】:What is intended behavior of Guava's Optional.or()?Guava 的 Optional.or() 的预期行为是什么?
【发布时间】:2019-03-05 22:41:21
【问题描述】:

我链接选项的方法的行为与我想象的不同 from reading the docs.

假设所有function_n都返回Optional<Foo>

public Foo getFooFromService() {
     return this.function_1()
         .or(this.function_2())
         .or(this.function_3())
         .or(DEFAULT_VAL)

我认为对于上面的代码,如果function_1 返回一个非缺失 Optional,那么程序将返回它的内部值(.get() 的结果)并且不对@987654326 做任何进一步的计算@和function_3

我的程序肯定会进行额外的计算

【问题讨论】:

  • 提示:似乎有一个需要Supplier的重载:如果存在,则返回包含的实例;否则供应商.get()。
  • @qqilihq 是的,我在回答中提到了它。我挑战你重写 OP 的 sn-p 以使用这种方法:)

标签: java guava optional chaining


【解决方案1】:

为了从getFooFromServicefunction_1 和三个ors 返回一个值,这意味着它们的参数将被评估。 function_2function_3 在任何情况下都会运行。

可能适合您的选项是采用 Supplier 的重载版本,这意味着延迟评估。

public abstract T or(Supplier<? extends T> supplier)

更新

这是一个@Beta 方法(可能会更改),我觉得它完全没用。它将Supplier&lt;? extend T&gt; 解析为T,从而破坏了构建链的机会。基本上,你不能重写你的 sn-p 来使用这个方法。

更新 1

但你可以切换到 Java 的 Optional 并写入

return function_1()
       .orElseGet(() -> function_2()
                        .orElseGet(() -> function_3()
                                         .orElse(DEFAULT_VAL)));

这不是那么富有表现力,但按预期工作。

我的格式很糟糕,但你明白了 ;)

【讨论】:

  • 哦,我知道现在有这种能力了。我通过迁移到 Java Optionals 并基本上按照您的建议解决了我的问题
  • @descript 你用orElseGets 代替了吗? :)
  • 我没有得到一件事,为什么预期 Optional secondChoice 的过载没有按照文档中的说明工作?
  • @AndrewTobilko 正确我使用了嵌套的 orElseGet( () -> function_n)。感谢您对答案的更新!它不如简单地链接 or()s 好,但它并没有太大的不同,而且肯定比一堆 if (isPresent()) then .get()
【解决方案2】:

Guava "gently recommends" to use Java's Optional

所以使用 Java 的Optional 来编写相当清晰的代码:

import java.util.*;
class Main {
  public static void main(String[] args) {
    new Main().getFooFromService();
  }
  String getFooFromService() {
    return this.function_1()
      .or(this::function_2) // Requires Java 9
      .or(this::function_3) // Requires Java 9
      .orElse("DEFAULT_VALUE");
  }

  Optional<String> function_1() {
    System.out.println("function_1 called");
    return Optional.empty();
  }

  Optional<String> function_2() {
    System.out.println("function_2 called");
    return Optional.of("b");
  }

  Optional<String> function_3() {
    System.out.println("function_3 called");
    return Optional.of("c");
  }
}

您会看到,在这种情况下,使用给定的设置,function_1function_2 被调用,而不是 function_3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 2021-10-15
    • 2016-11-12
    相关资源
    最近更新 更多