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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29216588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:35:28  来源:igfitidea点击:

How to ensure order of processing in java8 streams?

javajava-8java-stream

提问by membersound

I want to process lists inside an XMLjava object. I have to ensure processing all elements in order I received them.

我想处理XMLjava 对象内的列表。我必须确保按顺序处理所有元素。

Should I therefore call sequentialon each streamI use? list.stream().sequential().filter().forEach()

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

Or it it sufficient to just use the stream as long as I don't use parallelism? list.stream().filter().forEach()

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

采纳答案by Holger

You are asking the wrong question. You are asking about sequentialvs. parallelwhereas you want to process items in order, so you have to ask about ordering. If you have an orderedstream and perform operations which guarantee to maintain the order, it doesn't matter whether the stream is processed in parallel or sequential; the implementation will maintain the order.

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

The ordered property is distinct from parallel vs sequential. E.g. if you call stream()on a HashSetthe stream will be unordered while calling stream()on a Listreturns an ordered stream. Note that you can call unordered()to release the ordering contract and potentially increase performance. Once the stream has no ordering there is no way to reestablish the ordering. (The only way to turn an unordered stream into an ordered is to call sorted, however, the resulting order is not necessarily the original order).

有序属性不同于并行与顺序。例如,如果您调用stream()aHashSet流将是无序的,而调用stream()aList返回有序流。请注意,您可以调用unordered()以释放订购合同并可能提高性能。一旦流没有排序,就无法重新建立排序。(将无序流转换为有序流的唯一方法是调用sorted,但是,结果顺序不一定是原始顺序)。

See also the “Ordering” sectionof the java.util.streampackage documentation.

又见“订购”一节中的java.util.stream包文档

In order to ensure maintenance of ordering throughout an entire stream operation, you have to study the documentation of the stream's source, all intermediate operations and the terminal operation for whether they maintain the order or not (or whether the source has an ordering in the first place).

为了确保在整个流操作中保持排序,您必须研究流的源、所有中间操作和终端操作的文档,以确定它们是否维护顺序(或源是否在第一个中具有排序)地方)。

This can be very subtle, e.g. Stream.iterate(T,UnaryOperator)creates an ordered stream while Stream.generate(Supplier)creates an unorderedstream. Note that you also made a common mistake in your question as forEachdoes notmaintain the ordering. You have to use forEachOrderedif you want to process the stream's elements in a guaranteed order.

这可能非常微妙,例如,Stream.iterate(T,UnaryOperator)Stream.generate(Supplier)创建无序流的同时创建有序流。请注意,您在问题中也犯了一个常见错误,因为保持顺序。如果要以有保证的顺序处理流的元素,则必须使用。forEachforEachOrdered

So if your listin your question is indeed a java.util.List, its stream()method will return an orderedstream and filterwill not change the ordering. So if you call list.stream().filter() .forEachOrdered(), all elements will be processed sequentially in order, whereas for list.parallelStream().filter().forEachOrdered()the elements might be processed in parallel (e.g. by the filter) but the terminal action will still be called in order (which obviously will reduce the benefit of parallel execution).

因此,如果您list在问题中确实是 a java.util.List,则其stream()方法将返回一个有序流并且filter不会更改顺序。因此,如果您调用list.stream().filter() .forEachOrdered(),所有元素将按顺序依次处理,而对于list.parallelStream().filter().forEachOrdered()元素可能会并行处理(例如通过过滤器),但终端操作仍会按顺序调用(这显然会降低并行执行的好处) .

If you, for example, use an operation like

例如,如果您使用类似的操作

List<…> result=inputList.parallelStream().map(…).filter(…).collect(Collectors.toList());

the entire operation might benefit from parallel execution but the resulting list will always be in the right order, regardless of whether you use a parallel or sequential stream.

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