以下面的代码为例,它对列表进行排序,然后对其进行过滤:

public static void main(String[] args) {
        List<Integer> list = List.of(3,2,1);
        
        List<Integer> filtered =  list.stream()
                .sorted() // Does sorted() sort the entire array first ? Then pass the entire sorted output to filter ?
                .filter(x -> x < 3)
                .collect(Collectors.toList());
        
        System.out.println(filtered);
    }

整个sort()个先发生,然后传给filter()个吗?

那么,这不是违反了流应该做的事情吗?

我的意思是,他们应该处理one element at a time个.

推荐答案

整个sort()是否先发生,然后传递给filter()?

那么,这不是违反了流应该做的事情吗?

不,不是.看看documentation of the Stream IPA:

中间操作进一步分为无状态和

Stateful operations可能需要processentire input before producing a result.例如,一个人无法从中产生任何结果

这意味着sorted知道之前遇到的所有元素,即stateful.但是mapfilter不需要这些信息,它们是statelesslazy,这些操作总是一次处理一个来自流源的元素.

从技术上讲,通过孤立地查看单个元素来对管道中的内容进行排序是不可能的.sorted"一次"对all个元素进行操作,并将排序后的流分发给下一个操作.你可能会把sorted想象成一个新的流源.

让我们看看下面的流,并分析它将如何处理:

Stream.of("foo", "bar", "Alice", "Bob", "Carol")
    .filter(str -> !str.contains("r")) // lazy processing
    .peek(System.out::println)
    .map(String::toUpperCase)          // lazy processing
    .peek(System.out::println)
    .sorted()                          // <--- all data is being dumped into memory
    .peek(System.out::println)
    .filter(str -> str.length() > 3)   // lazy processing
    .peek(System.out::println)
    .findFirst();                      // <--- the terminal operation

sorted之前的操作filtermap将延迟地应用于流源的每个元素,并且仅在需要时apply.即filter将应用于"foo",它成功通过filter,并通过map操作进行转换.然后filter应用在"bar"上,它不会达到map.然后轮到"Alice"通过filter,然后map将在该字符串上执行.等等

请记住,sorted()需要所有数据来完成其工作,因此first filter将对源中的所有元素执行,map将应用于通过过滤器的每个元素.

然后sorted()操作将把流的所有内容转储到内存中,并对通过第一个过滤器的元素进行排序.

sorting之后,所有元素将再次被lazily one at a time处理.因此,second filter将被应用到only once(尽管3个元素已通过第一个过滤器并被排序)."Alice"将通过second filter并到达将返回该字符串的终端操作findFirst().

看看peek() make的调试输出,执行过程如上所述.

Java相关问答推荐

Spring安全实现多个SQL表身份验证

Mat. n_Delete()和Mat. n_release的区别

在Java Stream上调用collect方法出现意外结果

CAMEL 4中的SAXParseException

为什么我要创建一个单独的互斥体/锁对象?

我找不到&Quot;配置&的位置

在运行MVN测试时,为什么构建失败,并显示了java.lang.ClassNotFoundException:java.net.http.HttpResponse?

呈现文本和四舍五入矩形时出现的JavaFX窗格白色瑕疵

在Java中,在单个逻辑行中连接列表和单个元素的正确方法是什么?

如何让DTO接受空字符串字段,但如果它们不为空,则应用JPA验证?

如何集成语义发布和BitBucket(Java项目)

Java页面筛选器问题

如何在Java springboot中从一个端点发送多个时间响应?

何时调用密封层次 struct 的switch 中的默认情况

Oracle中从JSON中提取和插入数据

为什么mvn编译生命周期阶段不只是编译已更改的java文件?

将BlockingQueue+守护程序线程替换为执行器

Java KeyListener不工作或被添加

如何设置默认序列生成器分配大小

Spring Integration SFTP 连接失败 - 无法协商 kex 算法的密钥交换