IntStream :: noneMatch可以不评估流的所有元素的谓词吗?

时间:2014-12-24 12:07:18

标签: java java-8 java-stream

我读了IntStream::noneMatch的Javadoc。

它说:

  

返回此流的元素是否与提供的谓词匹配。 如果不需要确定结果,则可能无法评估所有元素的谓词。如果流为空,则返回true并且不评估谓词。

我想知道是否存在noneMatch不会评估流的所有元素的谓词并返回true的实际场景(在noneMatch返回false的情况下,很明显谓词仅在元素上进行评估,直到找到第一个匹配项。)

我能想到的唯一情况是,如果流管道有一个过滤器,其谓词是noneMatch谓词的确切负数,那么noneMatch可能会在不测试任何元素的情况下返回true。

但是,使用以下代码进行测试时:

boolean out = IntStream.range(1, 10000)
                  .filter(i -> i % 2 == 0)
                  .peek(System.out::println)
                  .noneMatch(i -> i % 2 == 1);
System.out.println(out);

我从2到9998得到偶数的输出:

2
4
6
...
9998
true

这意味着整个流被评估,即使过滤器只返回偶数整数,而noneMatch的谓词不需要找到奇数整数,所以它应该能够在不评估任何元素的情况下返回true。

那么,当Javadoc说May not evaluate on all elements.时,它是否只引用noneMatch返回false的情况?

编辑:

我只是想澄清一下,我的问题是为什么我发布的代码会评估整个流。我的问题是,是否存在noneMatch 返回 true 但未评估整个流的情况。

1 个答案:

答案 0 :(得分:4)

  

所以它应该能够在不评估任何元素的情况下返回true

不,为了检查元素的 none 是否匹配,它必须检查所有。换句话说,如果它返回true那么它肯定会查看所有内容。换句话说 - 你的逻辑依赖于谓词的作用,那么它如何在不评估任何元素的情况下返回,这意味着谓词永远不会被应用?

它可以返回true而不评估所有元素的唯一方法是,它只能通过流的类型和谓词的某些内容来判断。例如,如果流“知道”它是UUID引用的流,并且谓词是“匹配字符串”,那么它就不需要评估事物 - 但我怀疑是否有任何尝试一种优化。

如果(并且仅当)找到 与谓词匹配的内容时,它可以返回false而不查看其余项目。

例如,如果您将代码更改为:

boolean out = IntStream.range(1,10000)
               .peek(System.out::println)
               .noneMatch(i->i%4==3);
System.out.println(out);

然后你会得到输出:

1
2
3
false