Java 流 API

标签 java list lambda java-8 java-stream

当我们从集合列表中获取 Stream 时,幕后到底发生了什么?我发现很多博客都说Stream不存储任何数据。如果这是真的,请考虑代码片段:

List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);

Stream<Integer> stream = list.stream();
list = null;
stream.forEach(i -> System.out.print(i));

正如我们所见,即使 List(源)为 null,元素也可以流式访问。 这怎么可能?

最佳答案

Stream API 不知道 List 里面有什么。直到对第一个和剩余元素执行 lambda 表达式。

stream.forEach(i -> System.out.print(i));

上面的代码只不过是以下内容的快捷方式:

stream.forEach(new Consumer<String>() {
    @Override
    public void accept(String t) {
        System.out.println(t);
    }
});

lambda 表达式只是一个实现的接口(interface),即只有且只有一个方法的函数式接口(interface)。这个特殊的接口(interface)被注释为 @FunctionalInterface 并且可以表示为 lambda 表达式。

重点是,方法accept(String t)在实际调用之前不会执行 - lambda 也会发生同样的情况。考虑以下因素:

Consumer<String> consumer = i -> System.out.print(i);

// At this point the method `System.out.print(i)` remains not executed.
// Whatever expensive operation inside any lambda remains unexecuted 
// until its only method is called

stream.forEach(consumer);   // Now it encounters all the elements

因此,Stream 不知道元素,因为它将整个执行留给传递的 lambda 表达式。

<小时/>

顺便设置list = nullStream<Integer> 起不影响任何事情已经被创建了。源存储为 Spliterator<T> AbstractPipeline (line 123)

关于Java 流 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51712988/

相关文章:

java - 尝试运行我的项目时抛出 BeanCreationException

Java 列表电话簿

c# - 表达式——如何重用业务逻辑?如何将它们结合起来?

java - Google App Engine Java与cassandra修改线程组错误

java - 实体在 hibernate 中产生 classNotFound 异常

r - 数据框到结构化列表

python:将列表的每个元素组合到元组列表

haskell - lambda 内部的模式匹配

c++ - Lambda 转换函数指针比较

java - 将图像旋转 90 度或倍数的更快方法