通过谓词查找第一个元素

我刚刚开始使用Java 8 lambda,并且正在尝试实现一些我在函数式语言中惯用的东西。


例如,大多数功能语言都具有某种对序列进行操作的find函数,或者对返回谓词为的第一个元素的列表进行操作true。我看到的在Java 8中实现此目标的唯一方法是:


lst.stream()

    .filter(x -> x > 5)

    .findFirst()

但是,这对我来说似乎效率低下,因为过滤器将扫描整个列表,至少在我看来(可能是错误的)。有没有更好的办法?


慕容森
浏览 327回答 3
3回答

慕标5832272

不,过滤器不会扫描整个流。这是一个中间操作,它返回一个惰性流(实际上所有中间操作都返回一个惰性流)。为了说服您,您可以简单地进行以下测试:List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);int a = list.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .peek(num -> System.out.println("will filter " + num))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(x -> x > 5)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .findFirst()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .get();System.out.println(a);哪个输出:will filter 1will filter 1010您会看到实际上仅处理了流的前两个元素。因此,您可以采用完全正确的方法。

翻翻过去那场雪

但是这对我来说似乎效率低下,因为过滤器将扫描整个列表不,它不会-一旦找到满足谓词的第一个元素,它就会“中断”。您可以在流包javadoc中阅读有关懒惰的更多信息,尤其是(强调我的):许多流操作(例如过滤,映射或重复删除)可以延迟实施,从而暴露出进行优化的机会。例如,“使用三个连续的元音查找第一个字符串”不需要检查所有输入字符串。流操作分为中间(流产生)操作和终端(产生值或副作用)操作。中间操作总是很懒。

www说

import org.junit.Test;import java.util.Arrays;import java.util.List;import java.util.Optional;// Stream is ~30 times slower for same operation...public class StreamPerfTest {&nbsp; &nbsp; int iterations = 100;&nbsp; &nbsp; List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);&nbsp; &nbsp; // 55 ms&nbsp; &nbsp; @Test&nbsp; &nbsp; public void stream() {&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < iterations; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Optional<Integer> result = list.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(x -> x > 5)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .findFirst();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(result.orElse(null));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; // 2 ms&nbsp; &nbsp; @Test&nbsp; &nbsp; public void loop() {&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < iterations; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Integer result = null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (Integer walk : list) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (walk > 5) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = walk;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(result);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java