[英]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问题:
引用的所有地方都说由于流操作的管道衬里而没有消耗额外的内存。 原始流将通过管道传递。
本杰明博客的一个工作实例:
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.