mem*_*und 130 java java-8 java-stream
我想处理XML
java对象中的列表.我必须确保按顺序处理所有元素.
因此sequential
,stream
我应该每次使用我吗?
list.stream().sequential().filter().forEach()
或者只要我不使用并行性就足以使用流?
list.stream().filter().forEach()
Hol*_*ger 305
你问的是错误的问题.你问的是sequential
,parallel
而你想要按顺序处理项目,所以你必须询问订购.如果您有一个有序的流并执行保证维护顺序的操作,则无论是并行还是顺序处理流都无关紧要; 实施将维持秩序.
有序属性不同于并行和顺序.例如,如果你调用stream()
一个HashSet
同时调用流将是无序stream()
在List
返回的有序流.请注意,您可以致电unordered()
发布订购合同并可能提高性能.一旦流没有排序,就无法重新建立排序.(将无序流转换为有序的唯一方法是调用sorted
,但是,生成的顺序不一定是原始顺序).
又见"订购"一节中的java.util.stream
包文档.
为了确保整个流操作中的订购维护,您必须研究流的源,所有中间操作和终端操作的文档,以确定它们是否维护订单(或者源是否在第一个订单中有订单)地点).
这可能非常微妙,例如Stream.iterate(T,UnaryOperator)
在Stream.generate(Supplier)
创建无序流时创建有序流.请注意,您在问题中也犯了一个常见的错误,因为它没有保持顺序.如果要以保证顺序处理流的元素,则必须使用.forEach
forEachOrdered
因此,如果您list
的问题确实是a java.util.List
,则其stream()
方法将返回有序流,并且filter
不会更改排序.因此,如果您调用list.stream().filter() .forEachOrdered()
,所有元素将按顺序依次处理,而list.parallelStream().filter().forEachOrdered()
元素可能会并行处理(例如通过过滤器),但终端操作仍将按顺序调用(这显然会降低并行执行的好处) .
例如,如果您使用类似的操作
List<…> result=inputList.parallelStream().map(…).filter(…).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
整个操作可能会受益于并行执行,但无论您使用并行还是顺序流,结果列表始终都是正确的顺序.
Sai*_*pta 11
排序取决于源数据结构和中间流操作。假设您使用的是List
处理应该是有序的(因为filter
不会改变这里的顺序)。
S sequential()
Returns an equivalent stream that is sequential. May return itself, either because the stream was already sequential, or because the underlying stream state was modified to be sequential.
This is an intermediate operation.
Run Code Online (Sandbox Code Playgroud)
S parallel()
Returns an equivalent stream that is parallel. May return itself, either because the stream was already parallel, or because the underlying stream state was modified to be parallel.
This is an intermediate operation.
Run Code Online (Sandbox Code Playgroud)
S unordered()
Returns an equivalent stream that is unordered. May return itself, either because the stream was already unordered, or because the underlying stream state was modified to be unordered.
This is an intermediate operation.
Run Code Online (Sandbox Code Playgroud)
流可能有也可能没有定义的遭遇顺序。流是否具有遇到顺序取决于源和中间操作。某些流源(例如 List 或数组)本质上是有序的,而其他流源(例如 HashSet)则不是。一些中间操作,例如sorted(),可能会在无序流上强加遇到顺序,而其他操作可能会渲染无序的有序流,例如BaseStream.unordered()。此外,某些终端操作可能会忽略遇到顺序,例如 forEach()。
如果流是有序的,则大多数操作都被限制为按其遇到顺序对元素进行操作;如果流的源是一个包含[1, 2, 3]的List,那么执行map(x -> x*2)的结果一定是[2, 4, 6]。但是,如果源没有定义的遭遇顺序,则值 [2, 4, 6] 的任何排列都将是有效结果。
对于顺序流,存在或不存在相遇顺序不会影响性能,只会影响确定性。如果流是有序的,则在相同的源上重复执行相同的流管道将产生相同的结果;如果不排序,重复执行可能会产生不同的结果。
对于并行流,放宽排序约束有时可以实现更高效的执行。如果元素的排序不相关,则可以更有效地实现某些聚合操作,例如过滤重复项 (distinct()) 或分组缩减 (Collectors.groupingBy())。同样,本质上与遇到顺序相关的操作(例如 limit())可能需要缓冲来确保正确的顺序,从而削弱了并行性的优势。如果流具有遇到顺序,但用户并不特别关心该遇到顺序,则使用 unordered() 显式对流进行解序可能会提高某些有状态或终端操作的并行性能。然而,大多数流管道,例如上面的“块权重之和”示例,即使在排序约束下仍然可以有效地并行化。
归档时间: |
|
查看次数: |
68293 次 |
最近记录: |