【问题标题】:Apply filter to stream in Java将过滤器应用于Java中的流
【发布时间】:2017-08-23 18:37:23
【问题描述】:

鉴于以下代码,我希望输出为“-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);

【问题讨论】:

  • 你想用这个实现什么 - list.stream().filter(positive).allMatch(negative); ?从您的问题来看,您似乎期望输出为“-3-2-101231”,这与给定列表中的所有值相同。明确的要求是什么?

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


【解决方案1】:

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

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

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

用文档的话来说,Stream

--寻求懒惰。许多流操作,例如过滤、映射或重复删除,可以延迟实现,从而为优化提供机会。例如,“查找具有三个连续元音的第一个字符串”不需要检查所有输入字符串。流操作分为中间(流产生)操作和终端(产生价值或副作用)操作。中间操作总是惰性的。

还有,

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

【讨论】:

    【解决方案2】:

    对于“1”,该值为假。并且 false && (任何其他)将始终为 false,因此它不会评估其他任何内容。

    与 true 和 false 的 if 语句类似,它会进行惰性求值:

    public static void main(String[] args){
        System.out.println("Test1: False && anything else:");
        if (returnFalse() && returnTrue()) {
    
        }
    
        System.out.println("Test2: False || anything else:");
        if (returnFalse() || returnTrue()) {
    
        }
        System.out.println("Test3: True || anything else:");
        if (returnTrue() || returnTrue()) {
    
        }
        System.out.println("Test4: True && anything else:");
        if (returnTrue() && returnTrue()) {
    
        }
    
    
    }
    public static boolean returnFalse() {
        System.out.println("false");
        return false;
    }
    
    public static boolean returnTrue() {
        System.out.println("true");
        return true;
    }
    

    结果将是:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-18
      • 1970-01-01
      • 2020-05-17
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      相关资源
      最近更新 更多