Guava的Optional.or()的预期行为是什么?番石榴“温和地推荐”使用Java的Optional

问题描述 投票:2回答:2

我链式选项的方法并不像我认为的那样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()的结果)而不在function_2function_3上进行任何进一步的计算

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

java guava optional chaining
2个回答
5
投票

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

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

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

UPDATE

这是一个@Beta方法(一个可以改变的主题),我觉得它完全没用。它将Supplier<? extend T>解析为T,从而破坏了建立连锁店的机会。基本上,您无法重写您的代码段以使用此方法。

更新1

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

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

这不具有表现力,但按预期工作。

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


1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.