java - IntStream::noneMatch 不能评估流中所有元素的谓词吗?

标签 java java-8 java-stream

我阅读了 IntStream::noneMatch 的 Javadoc 。

它说:

Returns whether no elements of this stream match the provided predicate. May not evaluate the predicate on all elements if not necessary for determining the result. If the stream is empty then true is returned and the predicate is not evaluated. 

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

我能想到的唯一场景是,如果流管道有一个过滤器,其谓词是 noneMatch 谓词的精确负数,那么 noneMatch 可能会返回无需测试任何元素即可为真。

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

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 说可能不会对所有元素进行计算时,它是否仅指 noneMatch 返回 false 的情况?

编辑:

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

最佳答案

so it should be able to return true without evaluating any elements

不,为了检查没有元素匹配,它必须检查所有。换句话说,如果它返回 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

关于java - IntStream::noneMatch 不能评估流中所有元素的谓词吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27636711/

相关文章:

java - 如何在Java中使用内联类中断线程

java - JUnit中的Matchers.refEq()比较对象的引用

java - 使用通用供应商和 lambda 进行类型检查

java - 将空检查转换为可选

Java 通用 : Can a Generic extends another Generic class?

java - Play Framework 2.1 中 View 的相对时间

java - 使用 Java 8 Streams、map、filter、reduce 查找具有名字和姓氏的 Actor 曾工作过的电影

Java 8 和方法引用 - 特别是 compareToIgnoreCase

java - 在添加到集合之前过滤对象的最简洁方法?

java - 如何在继续流式传输时获取第一个元素?