应用过滤器以Java流式传输

时间:2017-03-30 02:51:49

标签: java filter java-8 java-stream predicate

鉴于以下代码,我希望输出为" -3-2-101231"因为过滤器应该遍历流的所有项目,从而打印正在评估的项目。当评估 allMatch 函数时,它应该打印" 1"因为它正在接收正整数流,所以它应该在发现第一个元素不是负数后发生短路。

为什么打印" -3-2-1011"而不是" -3-2-101231"?

    List<Integer> list = Arrays.asList(-3,-2,-1,0,1,2,3);
    Predicate<Integer> positive = i->{
        System.out.print(i);
        return i>0;
    };
    Predicate<Integer> negative = i->{
        System.out.print(i);
        return i<0;
    };

    list.stream().filter(positive).allMatch(negative);

2 个答案:

答案 0 :(得分:2)

不,过滤器不应遍历流中的每个项目。那将是一种浪费。一旦allMatch()操作看到非负项目,管道就会终止。

无法保证流中的所有项都会被过滤;保证是allMatch()测试的任何项目都首先通过了前面的过滤器。

您看到的输出是来自过滤器的-3 -2 -1 0 1,然后是来自最终谓词的1,这将终止该过程。当终端操作已经确定其结果时,不需要从上游过滤操作中获取2。

用文档的话来说,Stream

  

- 寻求懒惰。许多流操作(例如过滤,映射或重复删除)可以懒惰地实现,从而暴露出优化的机会。例如,&#34;找到第一个带有三个连续元音的字符串&#34;不需要检查所有输入字符串。流操作分为中间(流生成)操作和终端(生成价值或副作用)操作。中间操作总是很懒惰。

  

懒洋洋地处理流可以显着提高效率;在诸如上面的filter-map-sum示例的流水线中,过滤,映射和求和可以融合到数据的单个传递中,具有最小的中间状态。懒惰还允许在不必要时避免检查所有数据;对于诸如&#34;之类的操作,找到长于1000个字符的第一个字符串&#34;,只需要检查足够的字符串以找到具有所需特征的字符串,而不检查源中可用的所有字符串。 (当输入流是无限的而不仅仅是大的时候,这种行为变得更加重要。)

答案 1 :(得分:0)

对于&#39; 1&#39;值为false。和假&amp;&amp; (其他任何东西)总是假的,所以它不会评估任何其他东西。

同样,对于true和false的if语句,它都进行了延迟评估:

Test1: False && anything else:
false
Test2: False || anything else:
false
true
Test3: True || anything else:
true
Test4: True && anything else:
true
true

结果将是:

<iframe.+?((width="320")).+?(?!height=".+")src="https?:\/\/www.youtube.com\/embed\/([a-zA-Z0-9_-]{11})"[^>]+?><\/iframe>