【问题标题】:Can IntStream::noneMatch not evaluate the predicate on all the elements of the stream?IntStream::noneMatch 不能评估流中所有元素的谓词吗?
【发布时间】:2014-12-24 12:07:18
【问题描述】:

我阅读了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而不评估整个流的情况。

【问题讨论】:

  • 嗯,可能以后的版本可以检测到矛盾的Predicates。或者,未来的 API 可能有一个 Predicate.matchNone 常量,在传递给 Stream.filter 时会被识别。或者它可能识别map操作何时具有不依赖于其输入的函数(在这种情况下,检查单个元素就足以确定整个结果)。

标签: java java-8 java-stream


【解决方案1】:

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

不,为了检查 none 的元素是否匹配,它必须检查 everything。换句话说,如果它返回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

【讨论】:

  • 那么,您的意思是May not evaluate the predicate on all elements if not necessary for determining the result. 仅适用于noneMatch 返回false 的情况? Javadoc 没有明确说明,所以我想知道是否可能存在在不评估所有元素的情况下返回 true 的情况。
  • @Eran:我已经用 possible 场景编辑了我的答案,但我认为它没有实际实现,当然它不适用于你的示例给了。
猜你喜欢
  • 1970-01-01
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
相关资源
最近更新 更多