我阅读了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的情况。

最佳答案

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


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

07-24 09:34