use*_*411 9 java memory collections java-8 java-stream
我一直在阅读Java 8 Streams以及从数据源流式传输数据的方式,而不是让整个集合从中提取数据.
特别是我引用了一篇关于Java 8中的流的文章.
"没有存储.流没有值存储;它们通过一系列计算步骤从源(可能是数据结构,生成函数,I/O通道等)传输值." 来自:http: //www.drdobbs.com/jvm/lambdas-and-streams-in-java-8-libraries/240166818?pgno = 1
我理解从一个源一步一步地流式传输数据的概念.我不明白的是,如果你是从一个集合流式传输,怎么没有存储?该集合已存在于Heap中,您只是从该集合中流式传输数据,该集合已存在于"存储"中.
如果我只是使用标准for循环遍历集合,那么内存占用的区别是什么?
Stu*_*rks 25
关于流和存储的表态意味着甲流没有任何存储自身.如果流的源是一个集合,那么显然该集合具有存储来保存元素.
我们来看看那篇文章中的一个例子:
int sum = shapes.stream()
.filter(s -> s.getColor() == BLUE)
.mapToInt(s -> s.getWeight())
.sum();
Run Code Online (Sandbox Code Playgroud)
假设这shapes是一个Collection拥有数百万个元素的东西.可以想象,filter操作将迭代源中的元素并创建临时的结果集合,这些结果也可能包含数百万个元素.然后,mapToInt操作可以遍历该临时集合并生成其结果以进行求和.
这不是它的工作原理.没有临时的中间收藏.流操作是流水线操作的,因此从中filter传出的元素将被传递mapToInt并从而sum无需存储到集合中以及从集合中读取.
如果流源不是集合 - 比如,正在从网络集合中读取元素 - 则根本不需要任何存储.如下所示的管道:
int sum = streamShapesFromNetwork()
.filter(s -> s.getColor() == BLUE)
.mapToInt(s -> s.getWeight())
.sum();
Run Code Online (Sandbox Code Playgroud)
可能会处理数百万个元素,但它不需要在任何地方存储数百万个元素.
将流视为连接到水箱的喷嘴,水箱是您的数据结构。喷嘴没有自己的存储空间。当然,流提供的水(数据)来自具有存储空间的源,但流本身没有存储空间。将另一个喷嘴(流)连接到您的水箱(数据结构)不需要存储数据的全新副本。
集合是一种数据结构。根据问题,您决定使用哪个集合,例如 ArrayList、LinekedList (考虑时间和空间复杂性)。Stream只是一种处理工具,它让您的生活变得轻松。
其他区别是,您可以将Collection视为内存中的数据结构,您可以在其中添加、删除元素。在Stream中,您可以执行两种操作:
A。中间操作:过滤、映射、排序、对结果集进行限制
b.终端操作 :forEach,将结果集收集到集合中。
但如果您注意到,使用流您无法添加或删除元素。
Stream是一种迭代器,可以通过 Stream 来遍历集合。请注意,您只能遍历流一次,让我举个例子以便您更好地理解:
示例1:
List<String> employeeNameList = Arrays.asList("John","Peter","Sachin");
Stream<String> s = employeeNameList.stream();
// iterate through list
s.forEach(System.out :: println); // this work's perfectly fine
s.forEach(System.out :: println); // you will get IllegalStateException, stating stream already operated upon
Run Code Online (Sandbox Code Playgroud)
因此,您可以推断,集合可以根据需要迭代多次。但对于流来说,一旦你迭代,它就不会记住它应该做什么。所以,你需要再次指导它。
我希望,这是清楚的。
| 归档时间: |
|
| 查看次数: |
7052 次 |
| 最近记录: |