小编典典

如何确保 java8 流中的处理顺序?

all

我想处理XMLjava 对象中的列表。我必须确保处理所有元素才能收到它们。

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

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


阅读 112

收藏
2022-07-28

共1个答案

小编典典

你问错问题了。你问的是sequentialvs.parallel而你想 按顺序 处理项目,所以你必须问关于 ordering
的问题。如果您有一个 有序 流并执行保证保持顺序的操作,那么流是并行处理还是顺序处理都无关紧要;执行将维持秩序。

有序属性不同于并行与顺序。例如,如果您调用stream()aHashSet流将是无序的,而调用stream()aList返回有序流。请注意,您可以调用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());

整个操作可能会从并行执行中受益,但无论您使用并行还是顺序流,结果列表将始终处于正确的顺序。

2022-07-28