阅读了有关Java 8的一些知识后,我进入this博客文章,解释了有关流及其还原的一些知识,以及何时有可能使还原短路。在底部,它指出:
我知道findFirst
或findAny
可能会缩短还原量,因为一旦找到一个元素,就无需进一步处理。
但是,为什么对于allMatch
,noneMatch
和anyMatch
无法实现呢?对于allMatch
,如果找到与谓词不匹配的一个,则可以停止处理。一样没有。尤其是anyMatch
对我来说毫无意义,因为它几乎等于findAny
(除了返回的内容)?
对于findFirst/Any
,也可以说这三个可能不会短路,因为它可能需要评估所有值。
我缺少一些根本的区别吗?我不是很了解发生了什么吗?
最佳答案
有一个细微的差异,因为anyMatch
家族使用谓词,而findAny
家族不使用谓词。从技术上讲,findAny()
看起来像anyMatch(x -> true)
,而anyMatch(pred)
看起来像filter(pred).findAny()
。因此,这里有另一个问题。考虑我们有一个简单的无限流:
Stream<Integer> s = Stream.generate(() -> 1);
因此,将
findAny()
应用于此类流将始终会短路并完成,而应用anyMatch(pred)
取决于谓词是正确的。但是,让我们过滤无限流:Stream<Integer> s = Stream.generate(() -> 1).filter(x -> x < 0);
产生的流也无限吗?这是一个棘手的问题。它实际上不包含任何元素,但是要确定该元素(例如,使用
.iterator().hasNext()
),我们必须检查无限数量的基础流元素,因此该操作将永远不会完成。我也称此类流为无限。但是,使用此类流anyMatch
和findAny
将永远不会完成:Stream.generate(() -> 1).filter(x -> x < 0).anyMatch(x -> true);
Stream.generate(() -> 1).filter(x -> x < 0).findAny();
因此,
findAny()
也不能保证完成,这取决于先前的中间流操作。总而言之,我认为该博客文章具有误导性。我认为,在官方JavaDoc中可以更好地解释无限流的行为。