代码之家  ›  专栏  ›  技术社区  ›  Bartek

找到流到值-可选

  •  3
  • Bartek  · 技术社区  · 6 年前

    我希望在找到第一个值时终止流的执行。但是,当我运行下面的代码时,它会显示出调用了两个方法,即使值出现在 first method。

    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. 显示
    < Buff行情>

    如果存在值,则返回@code true,否则返回@code 错误}

    < /块引用> <开始=“2”>
  • findFirst()。
  • < Buff行情>

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

    < /块引用>

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

    first
    second
    someValue
    

    如果第一个值存在,而不是执行 second method,如何退出执行?

    2 回复  |  直到 6 年前
        1
  •  6
  •   Jacob G.    6 年前
    < Buff行情>

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

    < /块引用>

    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
    

    防止P> 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
  •  2
  •   ernest_k Petronella    6 年前

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

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

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

    它仍然会执行 first() and second() 立即。