Java 8:Stream.filter 未按预期运行

Posted

技术标签:

【中文标题】Java 8:Stream.filter 未按预期运行【英文标题】:Java 8 : Stream.filter not running as expected 【发布时间】:2021-04-05 17:18:25 【问题描述】:

给定:

    List<String> str = Arrays.asList ("my", "pen", "is", "your", "pen");
    Predicate<String> test = s -> 
        int i = 0;
        boolean result = s.contains ("pen");
        System.out.print((i++) + ":");
        return result;
    ;

这打印:0:0:

    str.stream().filter(test).findFirst();

这会打印 0:0:0:0:0:

    str.stream().filter(test).collect(Collectors.toList());

让我困惑的是,无论是findFirst还是collect,无论终端操作是否短路,他们两者都应该遍历列表中的每个项目,对吧?

那么为什么在第一个示例 findFirst 中,“0:”被打印两次,而不仅仅是一次,而不是5 次? p>

【问题讨论】:

当 API 读取“find first”时,为什么会期望它进一步迭代? 您的计数打印使用的是后增量,并且始终为零。 【参考方案1】:

让我困惑的是,无论是findFirst还是collect,无论终端操作是否短路,它们都应该遍历列表中的每一项,对吧?

能够在不检查整个流的情况下返回正是导致操作(如findFirst)短路的原因。见Streams javadoc。

Streams 文档实际上并没有承诺如何或是否评估您的谓词。它只是保证它将返回与谓词匹配的流的第一个元素。

【讨论】:

【参考方案2】:

第一个Stream的思想是迭代找到第一次出现的“pen”,所以Predicate迭代数组直到找到第一个匹配过滤条件的元素。因此,您只会看到两个“0:”。 Official documentation

【讨论】:

以上是关于Java 8:Stream.filter 未按预期运行的主要内容,如果未能解决你的问题,请参考以下文章

IOS 8 高度约束动画未按预期工作

java 8 List Filter

情节提要未按预期工作,Xcode 8.3 beta 3

Java8-stream findAny()注意点

基数排序的并行版本未按预期运行(Java)

Mandelbrot 集函数未按预期执行