为了账号安全,请及时绑定邮箱和手机立即绑定

通过谓词查找第一个元素

通过谓词查找第一个元素

慕容森 2019-12-09 15:44:44
我刚刚开始使用Java 8 lambda,并且正在尝试实现一些我在函数式语言中惯用的东西。例如,大多数功能语言都具有某种对序列进行操作的find函数,或者对返回谓词为的第一个元素的列表进行操作true。我看到的在Java 8中实现此目标的唯一方法是:lst.stream()    .filter(x -> x > 5)    .findFirst()但是,这对我来说似乎效率低下,因为过滤器将扫描整个列表,至少在我看来(可能是错误的)。有没有更好的办法?
查看完整描述

3 回答

?
慕标5832272

TA贡献1966条经验 获得超4个赞

不,过滤器不会扫描整个流。这是一个中间操作,它返回一个惰性流(实际上所有中间操作都返回一个惰性流)。为了说服您,您可以简单地进行以下测试:


List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);

int a = list.stream()

            .peek(num -> System.out.println("will filter " + num))

            .filter(x -> x > 5)

            .findFirst()

            .get();

System.out.println(a);

哪个输出:


will filter 1

will filter 10

10

您会看到实际上仅处理了流的前两个元素。


因此,您可以采用完全正确的方法。


查看完整回答
反对 回复 2019-12-09
?
翻翻过去那场雪

TA贡献2065条经验 获得超14个赞

但是这对我来说似乎效率低下,因为过滤器将扫描整个列表


不,它不会-一旦找到满足谓词的第一个元素,它就会“中断”。您可以在流包javadoc中阅读有关懒惰的更多信息,尤其是(强调我的):


许多流操作(例如过滤,映射或重复删除)可以延迟实施,从而暴露出进行优化的机会。例如,“使用三个连续的元音查找第一个字符串”不需要检查所有输入字符串。流操作分为中间(流产生)操作和终端(产生值或副作用)操作。中间操作总是很懒。


查看完整回答
反对 回复 2019-12-09
?
www说

TA贡献1775条经验 获得超8个赞

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 {


    int iterations = 100;

    List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);



    // 55 ms

    @Test

    public void stream() {


        for (int i = 0; i < iterations; i++) {

            Optional<Integer> result = list.stream()

                    .filter(x -> x > 5)

                    .findFirst();


            System.out.println(result.orElse(null));

        }

    }


    // 2 ms

    @Test

    public void loop() {


        for (int i = 0; i < iterations; i++) {

            Integer result = null;

            for (Integer walk : list) {

                if (walk > 5) {

                    result = walk;

                    break;

                }

            }

            System.out.println(result);

        }

    }

}


查看完整回答
反对 回复 2019-12-09
  • 3 回答
  • 0 关注
  • 333 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信