问题描述
在Java 8上读了一下,我得到了博客文章解释了一些关于流和减少它们的内容,以及什么时候可以缩短缩减。在底部说明:
Reading up a bit on Java 8, I got to this blog post explaining a bit about streams and reduction of them, and when it would be possible to short-circuit the reduction. At the bottom it states:
我得到 findFirst
或 findAny
可能会缩短缩减,因为一旦找到元素,您就不需要再进行处理了。
I get that findFirst
or findAny
may short-circuit the reduction, because as soon af you find an element, you don't need to process any further.
但为什么 allMatch
, noneMatch $ c $无法实现c>和
anyMatch
?对于 allMatch
,如果找到与谓词不匹配的一个,则可以停止处理。同样没有。并且 anyMatch
特别对我没有意义,因为它几乎等于 findAny
(除了什么是返回)?
But why would this not be possible for allMatch
, noneMatch
and anyMatch
? For allMatch
, if you find one which doesn't match the predicate, you can stop processing. Same for none. And anyMatch
especially doesn't make sense to me, as it it pretty much equal to findAny
(except for what is returned)?
说这三个可能不会短路,因为它可能需要评估所有的值,也可以说 findFirst /任何
。
Saying that these three may not short-circuit, because it may take evaluating all the values, could also be said for findFirst/Any
.
我缺少一些根本区别吗?我真的不明白发生了什么吗?
Is there some fundamental difference I'm missing? Am I not really understanding what is going on?
推荐答案
有一个细微的区别,因为 anyMatch
family使用谓词,而 findAny
family则不使用谓词。技术上 findAny()
看起来像 anyMatch(x - > true)
和 anyMatch(pred )
看起来像 filter(pred).findAny()
。所以这里有另一个问题。考虑我们有一个简单的无限流:
There's a subtle difference, because anyMatch
family uses a predicate, while findAny
family does not. Technically findAny()
looks like anyMatch(x -> true)
and anyMatch(pred)
looks like filter(pred).findAny()
. So here we have another issue. Consider we have a simple infinite stream:
Stream<Integer> s = Stream.generate(() -> 1);
所以应用 findAny()
应用时,此类流将始终短路并完成anyMatch(pred)
取决于谓词。但是,让我们过滤我们的无限流:
So it's true that applying findAny()
to such stream will always short-circuit and finish while applying anyMatch(pred)
depends on the predicate. However let's filter our infinite stream:
Stream<Integer> s = Stream.generate(() -> 1).filter(x -> x < 0);
结果流是否也是无限的?这是一个棘手的问题。它实际上不包含任何元素,但要确定这一点(例如,使用 .iterator()。hasNext()
)我们必须检查无限数量的底层流元素,所以这个操作永远不会完成。我也称这种流为无限。但是使用这样的流 anyMatch
和 findAny
将永远不会完成:
Is the resulting stream infinite as well? That's a tricky question. It actually contains no elements, but to determine this (for example, using .iterator().hasNext()
) we have to check the infinite number of underlying stream elements, so this operation will never finish. I would call such stream an infinite as well. However using such stream both anyMatch
and findAny
will never finish:
Stream.generate(() -> 1).filter(x -> x < 0).anyMatch(x -> true);
Stream.generate(() -> 1).filter(x -> x < 0).findAny();
所以 findAny()
不保证完成任一项,这取决于之前的中间流操作。
So findAny()
is not guaranteed to finish either, it depends on the previous intermediate stream operations.
总而言之,我认为该博客文章非常具有误导性。在我看来,无限流行为在官方。
To conclude I would rate that blog-post as very misleading. In my opinion infinity stream behavior is better explained in official JavaDoc.
这篇关于Java 8流短路的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!