阅读了一些有关 Java 8 的内容,我必须this https://thecannycoder.wordpress.com/2014/08/10/collectors-part-1-reductions-and-short-circuiting-operations%E2%80%8F/博客文章解释了一些关于流和减少流的信息,以及何时可以短路减少。底部写着:
请注意以下情况findFirst
or findAny
我们只需要与谓词匹配的第一个值(尽管findAny
不保证返回第一个)。但是,如果流没有顺序,那么我们期望findFirst
表现得像findAny
。行动allMatch
, noneMatch
and anyMatch
可能根本不会短路流,因为它可能需要评估所有值来确定运算符是否是true
or false
。因此,使用这些的无限流可能不会终止。
我明白了findFirst
or findAny
可能会使还原短路,因为一旦找到元素,就不需要进一步处理。
但为什么这对allMatch
, noneMatch
and anyMatch
? For allMatch
,如果发现与谓词不匹配,则可以停止处理。没有人也一样。和anyMatch
特别是对我来说没有意义,因为它几乎等于findAny
(除了返回的内容)?
说这三个不能短路,因为可能需要评估所有值,也可以说findFirst/Any
.
我缺少一些根本的区别吗?我真的不明白发生了什么吗?
有一个微妙的区别,因为anyMatch
family 使用谓词,而findAny
家人没有。从技术上来说findAny()
好像anyMatch(x -> true)
and 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
and findAny
永远不会完成:
Stream.generate(() -> 1).filter(x -> x < 0).anyMatch(x -> true);
Stream.generate(() -> 1).filter(x -> x < 0).findAny();
So findAny()
也不保证完成,它取决于之前的中间流操作。
总而言之,我认为该博文非常具有误导性。在我看来,无限流行为在官方中得到了更好的解释JavaDoc https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)