这个问题在这里已有答案:
我想在找到第一个值时终止流的执行。但是,当我在下面运行代码时,它会显示即使第一个方法存在值,也会调用两个方法。
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();
}
我在文档中检查了:
如果存在值,则返回{@code true},否则返回{@code false}。
返回描述此流的第一个元素的{@link Optional},如果流为空,则返回空的{@code Optional}。如果流没有遭遇顺序,则可以返回任何元素。
所以它遇到的第一个条件,第二个条件似乎也满足,因为它返回:
first
second
someValue
如果第一个值存在,如何退出执行,而不执行第二个方法?
如果第一个值存在,如何退出执行,而不执行第二个方法?
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
问题不在于findFirst
不是短路,而是Stream.of(first(), second())
导致first()
和second
的立即(不延迟)执行。它基本上被评估为任何普通表达式。
换句话说,即使你的主要方法是公正的
final public static void main(String[] args) throws Exception {
Stream.of(first(), second());
}
它仍将立即执行first()
和second()
。