在 Java 8 中链接可选

2022-08-31 11:06:38

寻找一种链接可选项的方法,以便返回存在的第一个可选项。如果没有,则应返回。Optional.empty()

假设我有几个这样的方法:

Optional<String> find1()

我试图链接它们:

Optional<String> result = find1().orElse( this::find2 ).orElse( this::find3 );

但这当然不起作用,因为期望一个值并期望一个.orElseorElseGetSupplier


答案 1

使用流:

Stream.of(find1(), find2(), find3())
    .filter(Optional::isPresent)
    .map(Optional::get)
    .findFirst();

如果需要懒惰地评估查找方法,请使用 supplier 函数:

Stream.of(this::find1, this::find2, this::find3)
    .map(Supplier::get)
    .filter(Optional::isPresent)
    .map(Optional::get)
    .findFirst();

答案 2

受到Sauli答案的启发,可以使用这种方法。flatMap()

Stream.of(this::find1, this::find2, this::find3)
  .map(Supplier::get)
  .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty))
  .findFirst();

将可选转换为流很麻烦。显然,这将通过JDK9修复。所以这可以写成

Stream.of(this::find1, this::find2, this::find3)
  .map(Supplier::get)
  .flatMap(Optional::stream)
  .findFirst();

Java 9 发布后的更新

虽然最初的问题是关于Java 8的,但Opport::or是在Java 9中引入的。有了它,问题可以解决如下

Optional<String> result = find1()
  .or(this::find2)
  .or(this::find3);

推荐