直到找到值 - 可选[重复]

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

这个问题在这里已有答案:

我想在找到第一个值时终止流的执行。但是,当我在下面运行代码时,它会显示即使第一个方法存在值,也会调用两个方法。

public static void main(String[] args) {

        Optional<String> s = Stream.of(first(), second())
                .filter(Optional::isPresent)
                .findFirst()
                .flatMap(Function.identity());

        System.out.println(s.get());
    }

    private static Optional<String> first() {
        System.out.println("first");
        return Optional.of("someValue");
    }

    private static Optional<String> second() {
        System.out.println("second");
        return Optional.empty();
    }

我在文档中检查了:

  1. isPresent

如果存在值,则返回{@code true},否则返回{@code false}。

  1. 使用FindFirst()

返回描述此流的第一个元素的{@link Optional},如果流为空,则返回空的{@code Optional}。如果流没有遭遇顺序,则可以返回任何元素。

所以它遇到的第一个条件,第二个条件似乎也满足,因为它返回:

first
second
someValue

如果第一个值存在,如何退出执行,而不执行第二个方法?

java java-stream optional
2个回答
6
投票

如果第一个值存在,如何退出执行,而不执行第二个方法?

Stream#findFirst是一种短路终端操作。但是,当您调用Stream.of(first(), second())时,将调用这些方法。这可以通过以下代码段证明:

Optional<String> s = Stream.of(first(), second())
                           .peek($ -> System.out.println("Hello World!"))
                           .filter(Optional::isPresent)
                           .findFirst()
                           .flatMap(Function.identity());

System.out.println(s.get());

输出:

first
second
Hello World!
someValue

为了防止first()second()在调用Stream#of时执行,一种解决方案是将它们包装在Supplier<Optional<String>>中:

Stream<Supplier<Optional<String>>> stream = Stream.of(Test::first, Test::second);

Optional<String> s = stream.map(Supplier::get)
                           .filter(Optional::isPresent)
                           .findFirst()
                           .flatMap(Function.identity());

System.out.println(s.get());

输出:

first
someValue

2
投票

问题不在于findFirst不是短路,而是Stream.of(first(), second())导致first()second的立即(不延迟)执行。它基本上被评估为任何普通表达式。

换句话说,即使你的主要方法是公正的

final public static void main(String[] args) throws Exception {
    Stream.of(first(), second());
}

它仍将立即执行first()second()

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