Java 8 findFirst()。isPresent()比count()>更有效吗? 0?

时间:2016-09-26 23:41:39

标签: java java-8 java-stream

鉴于我有一个流Stream<T> stream = list.stream().filter(some predicate),其中列表非常大,通过执行以下操作来检查流是否为空是否更有效:stream.count() > 0或执行:stream.findFirst().isPresent()

3 个答案:

答案 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进行编程以编码您的意图,因此当您只想知道是否存在匹配时,不应使用Optionalfind…明确表达了您的意图,并可能在未来的实施或更复杂的情况下获得更高的利益。

答案 2 :(得分:2)

findAny(如果您不需要订购,则优于findFirstanyMatchshort-circuiting operations,这意味着他们可以提早返回,而不会占用整个流条件允许。这在他们的方法javadocs中被提及并链接。 count() is not

如果流的最后阶段仍然使用具有SIZED特征的分词符,那么count() 可能与其他两个选项一样快。但这是一个比短路更弱的特性,因为中间流操作 - 例如filter() - 很可能会丢弃SIZED方面。

所有这些信息都可以从包文档中收集,强烈推荐阅读。