如何确保java8stream中的处理顺序?
我想处理XML
java对象内的列表。 我必须确保处理所有元素,以便我收到它们。
因此,我应该在每个使用的stream
上调用sequential
吗? list.stream().sequential().filter().forEach()
或者只要不使用并行性就可以使用stream? list.stream().filter().forEach()
你问的是错误的问题。 你在问sequential
和parallel
而你想sequential
处理项目,所以你必须询问有关的顺序 。 如果你有一个有序的stream并且执行保证维护顺序的操作,那么这个stream是并行还是连续处理并不重要; 执行将维持顺序。
有序属性不同于并行与顺序。 例如,如果您在HashSet
上调用stream()
,则在调用List
上的stream()
时会返回一个有序stream,而stream将无序。 请注意,您可以调用unordered()
来释放订购合同,并可能提高性能。 一旦stream没有sorting,就没有办法重新build立sorting。 (将无序stream转换为有序的唯一方法是调用sorted
,但是,结果顺序不一定是原始顺序)。
另请参见java.util.stream
包文档的“Ordering”部分 。
为了确保在整个stream操作中维持sorting,您必须研究stream的源文档,所有中间操作和terminal操作,以确定它们是否维持顺序(或者源是否在第一个顺序地点)。
这可以是非常微妙的,例如Stream.iterate(T,UnaryOperator)
创build一个有序的stream,而Stream.generate(Supplier)
创build一个无序的stream。 请注意,您也在您的问题中犯了一个常见错误,因为每个都不保留sorting。 如果要按照保证顺序处理stream的元素,则必须使用forEachOrdered
。
所以如果你的问题list
确实是一个java.util.List
,它的stream()
方法将返回一个有序的stream, filter
不会改变sorting。 所以如果你调用list.stream().filter() .forEachOrdered()
,所有的元素将按顺序处理,而对于list.parallelStream().filter().forEachOrdered()
元素可能被并行处理例如通过filter),但terminal行为仍然会被调用(这显然会降低并行执行的好处)。
例如,如果你使用类似的操作
List<…> result=inputList.parallelStream().map(…).filter(…).collect(Collectors.toList());
整个操作可能会从并行执行中受益,但是无论使用并行还是顺序stream,结果列表总是按照正确的顺序排列。
list.stream()。顺序()。过滤()。forEach()这样
将总是按列表本身的顺序处理列表。
但是,如果我们使用
list.stream()。平行()
那么订单不能保证其余的操作。