繁体   English   中英

java-8 streams:来自中间操作的新流是否在不增加内存的情况下返回?

[英]java-8 streams : Are new streams from intermediate operations returned without increase in memory?

我试图详细了解java-8流。

上的oracle文档页面:

Streams在几个方面与集合不同:

没有存储空间 流不是存储元素的数据结构; 相反,它通过计算操作管道传递来自诸如数据结构,数组,生成器函数或I / O通道的源的元素。

流操作和管道

流操作分为中间操作和终端操作,并组合成流管道。

流管道由源(例如集合,数组,生成器函数或I / O通道)组成; 然后是零个或多个中间操作,例如Stream.filter或Stream.map; 和一个终端操作,如Stream.forEach或Stream.reduce。

中间操作返回一个新流

除了文档,我还经历了相关的SE问题:

Java中的流如何影响内存消耗?

引用的所有地方都说由于流操作的管道衬里而没有消耗额外的内存。 原始流将通过管道传递。

本杰明博客的一个工作实例:

List<String> myList =
    Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList
    .stream()
    .filter(s -> s.startsWith("c"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(System.out::println);

但是当像filter, map and sorted这样的中间操作返回新流时,为什么它不会增加内存消耗? 我在这里错过了什么吗?

我认为你在字面上解释了文档中的“无存储”部分,因为“没有内存增加”。 这种解释是错误的:“无存储”意味着“没有存储流元素”。 Stream对象本身表示固定开销,与空集合具有一些开销的方式相同,因此流本身的大小不计算在内。

但是当像filter,map和sorted这样的中间操作返回新流时,为什么它不会增加内存消耗?

确实如此。 然而,尺寸的增加是固定的,即O(1)增加。 这与集合形成对比,集合中制作n元素集合的副本的增加是O(n)。

请尝试阅读http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html和/或http://winterbe.com/posts/2014/07 / 31 / java8-stream-tutorial-examples / ,我想,你试图弄清楚的概念得到了很好的解释。

基本上你可以看到的是,对于大多数中间操作,它们并不是每次操作都会同时发生。 一次1个元素,它们通过所有中间操作处理,并根据终端操作丢弃或放入集合/添加到总和/打印等。 如果它是一个收集类型的终端操作,那么在创建这个新集合时当然会有一些内存开销,但是在流中单独保存没有任何东西。 这也是为什么你不能两次(部分)迭代流的原因。

但是有一些操作,例如stream.sorted(func),在处理过程中可能需要一些状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM