如何确保java8stream中的处理顺序?

我想处理XML java对象内的列表。 我必须确保处理所有元素,以便我收到它们。

因此,我应该在每个使用的stream上调用sequential吗? list.stream().sequential().filter().forEach()

或者只要不使用并行性就可以使用stream? list.stream().filter().forEach()

你问的是错误的问题。 你在问sequentialparallel而你想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()。平行()

那么订单不能保证其余的操作。