鉴于我有一个流Stream<T> stream = list.stream().filter(some predicate)
,其中列表非常大,通过执行以下操作来检查流是否为空是否更有效:stream.count() > 0
或执行:stream.findFirst().isPresent()
?
答案 0 :(得分:11)
我建议使用list.stream().anyMatch(some predicate)
,对于这种情况,这是一个终端操作。它不仅比stream.count()
更有效,而且不会挂在无限流上。
答案 1 :(得分:6)
如果你想知道的是,是否匹配,你应该使用
list.stream().anyMatch(some predicate)
,不仅因为它更有效率,而且因为它是表达你意图的正确习惯。
正如其他人所说的那样,anyMatch
是短路的,这意味着它会在第一场比赛时停止,而count
将会如名称所示,计算所有返回前匹配。根据流内容,这可以产生巨大的性能差异。但请注意,通过使用,您可以使count
同样有效
list.stream().filter(some predicate).limit(1).count() > 0
然后,它也将在第一次出现后停止,但是,如上所述,anyMatch
仍然是表达您是否有任何匹配感兴趣的首选方式。当任务是找出至少 n
匹配时,事情会发生变化。然后,.limit(n).count() > n-1
(或>= n
)成为自然的习语。
请注意findFirst()
与其他解决方案不同,因为它的答案取决于排序。因此,如果您只想知道是否匹配,则应使用findAny()
代替。仍然存在理论差异,因为需要返回匹配值,而只是告诉是否存在匹配,如anyMatch
那样,尽管目前这种差异仅在于构造{{1}实例,因此可以忽略不计。
但是,由于您正在针对API进行编程以编码您的意图,因此当您只想知道是否存在匹配时,不应使用Optional
。 find…
明确表达了您的意图,并可能在未来的实施或更复杂的情况下获得更高的利益。
答案 2 :(得分:2)
findAny
(如果您不需要订购,则优于findFirst
而anyMatch
为short-circuiting operations,这意味着他们可以提早返回,而不会占用整个流条件允许。这在他们的方法javadocs中被提及并链接。 count()
is not。
如果流的最后阶段仍然使用具有SIZED特征的分词符,那么count()
可能与其他两个选项一样快。但这是一个比短路更弱的特性,因为中间流操作 - 例如filter()
- 很可能会丢弃SIZED方面。
所有这些信息都可以从包文档中收集,强烈推荐阅读。