Java 8 findFirst().isPresent()是否比count()更有效>;0?
假设我有一个流Java 8 findFirst().isPresent()是否比count()更有效>;0?,java,java-8,java-stream,Java,Java 8,Java Stream,假设我有一个流stream=list.stream().filter(一些谓词),其中列表非常大,那么通过执行以下操作检查流是否为非空是否更有效:stream.count()>0,或者执行以下操作:stream.findFirst().isPresent()?我建议使用list.stream().anyMatch(一些谓词),这正是这种情况下的一个终端操作。它不仅比stream.count()更有效,而且不会挂起无限的流。如果您只想知道是否存在匹配,您应该使用 list.stream().any
stream=list.stream().filter(一些谓词)
,其中列表非常大,那么通过执行以下操作检查流是否为非空是否更有效:stream.count()>0
,或者执行以下操作:stream.findFirst().isPresent()
?我建议使用list.stream().anyMatch(一些谓词)
,这正是这种情况下的一个终端操作。它不仅比stream.count()
更有效,而且不会挂起无限的流。如果您只想知道是否存在匹配,您应该使用list.stream().anyMatch(某些谓词)
,不仅因为它更有效,而且因为它是表达意图的正确习惯用法
正如其他人所说,anyMatch
是短路,这意味着它将在第一次匹配时停止,而count
将,顾名思义,在返回之前对所有匹配进行计数。根据流的内容,这可能会造成巨大的性能差异。但是请注意,您可以使count
同样有效通过使用
list.stream().filter(某些谓词).limit(1).count()>0
然后,它也会在第一次出现后停止,但正如所说,anyMatch
仍然是表示您对是否有匹配感兴趣的首选方式。当任务是确定是否至少有n
匹配时,情况会发生变化。然后,.limit(n).count()>n-1
(或=n
)成为自然的习语
请注意,findFirst()
与其他解决方案不同,因为它的答案取决于顺序。因此,如果您只想知道是否存在匹配项,则应使用findAny()
相反。尽管如此,由于返回匹配值的要求,与仅仅判断是否存在匹配(如anyMatch
所做的)相比,理论上还是存在差异,尽管目前这种差异仅存在于可选
实例的构造中,因此可以忽略不计
但是,由于您是根据API编程来编码您的意图,因此当您只想知道是否存在匹配时,不应使用find…
。anyMatch
清楚地表达了您的意图,并且在未来的实现或更复杂的场景中可能会有更大的好处。findAny
(如果您不需要订购,这比findFirst
更可取)和anyMatch
是,这意味着如果条件允许,他们可以提前返回而不消耗整个流。这在他们的方法中提到并链接。count()
如果流的最后阶段仍然使用具有该特性的拆分器,则count()
可能与其他两个选项一样快。但这是一个比短路弱得多的特性,因为中间流操作(如filter()
)很可能会丢弃大小方面
所有这些信息都可以从软件包文档中收集,强烈建议阅读。这取决于它是哪个
列表
实现,但它甚至不可比较,因为它在流中移动您。对于无限流,count()
甚至不会终止;即使对于有限流,它也必须在返回之前遍历整个流。而findFirst()
或findAny()
或anyMatch(e->true)
短路,它们在找到元素时停止。这里真正的教训是,正确的问题不是关于效率,而是关于正确性。使用findXxx
或xxxMatch
更好,不是因为它们更有效,而是因为它们更接近于表达您真正想要了解的属性。它们的效率更高,这仅仅是对库提出了更好的查询的一个令人愉快的副作用。由于问题的代码包含了一个过滤器操作,因此无法通过测试每个元素来获得匹配元素的数量。除了热点优化器可能检测到(在顺序上下文中)考虑到结果数字的使用方式,计算计数是不必要的。在任何一种情况下,count
都是最差的赌注。@霍尔格我没有提出其他要求。我只是想指出,在有限的情况下,count
可能同样快。可想象的优化类似于过滤器(Predictate.TRUE)
(如果存在的话)保留源拆分器。我只想提到的是,在什么情况下可以使用可预测的大小是众所周知的(这就是为什么我在回答时不使用它,因为它在这里不适用),好的,一个总是-true
谓词并不存在,这可能不是那么引人注目,但更糟糕的是,在Oracle的JRE/OpenJDK中,size
spliterators中的已知数字直到Java 9…被授予时才被使用,这是相当重要的theoretical@Holger听起来你好像不同意我说的话。也许我误解了我的意思你昨天的回答,我想,我忽略了“唯一的”…我没有投反对票,以防你想知道。