Google Guava可选 - 如何使多个链式表达式短路

时间:2014-12-20 05:06:30

标签: java java-8 guava

假设我有多个方法,每个方法都返回Optional。我想将它们链接在一起,这样如果其中一个返回带有值的Optional,那么链应该停止传播并且应该在那个点停止。例如让我们说f1,f2,f3都返回Optional。

如果我这样做,

Optional<T> result = f1.or(f2).or(f3);

我看到即使f2返回Optional.of(t),f3仍会被调用。

我希望它表现得像一个短路表达式,但它不会那样工作。

任何人都可以帮助我。

2 个答案:

答案 0 :(得分:1)

您需要使用Supplier来使其变得懒惰:

Stream.<Supplier<Optional<T>>>of(this::f1, this::f2, this::f3)
        .map(Supplier::get)
        .filter(Optional::isPresent)
        .map(Optional::get)
        .findFirst();

示例,与Mike的回答一样:

public class LazyOptional {
    public static void main(String... args) {
        new LazyOptional().run();
    }

    public void run() {
        Stream.<Supplier<Optional<String>>>of(this::f1, this::f2, this::f3)
                .map(Supplier::get)
                .peek(System.out::println)
                .filter(Optional::isPresent)
                .map(Optional::get)
                .findFirst();
    }

    public Optional<String> f1() {
        return Optional.empty();
    }

    public Optional<String> f2() {
        return Optional.of("a");
    }

    public Optional<String> f3() {
        return Optional.of("b");
    }
}

输出:

Optional.empty
Optional[a]

答案 1 :(得分:0)

您可以通过在Java 8中使用短路流来完成此操作。您可以将映射应用于结果,以使结果也以Optional<T>而不是Optional<Optional<T>>形式出现。< / p>

Optional<Integer> e1 = Optional.empty();
Optional<Integer> e2 = Optional.empty();
Optional<Integer> p = Optional.of(1337);
Optional<Integer> e3 = Optional.empty();
Optional<Integer> e4 = Optional.empty();

// peek used to show output
Optional<Integer> first = Stream.of(e1, e2, p, e3, e4)
    .peek(System.out::println)
    .filter(Optional::isPresent)
    .map(Optional::get)
    .findFirst();

输出:

Optional.empty
Optional.empty
Optional[1337]