如何确保java8流中的处理顺序? [英] How to ensure order of processing in java8 streams?

查看:37
本文介绍了如何确保java8流中的处理顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

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

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

推荐答案

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

You are asking the wrong question. You are asking about sequential vs. parallel whereas you want to process items in order, so you have to ask about ordering. If you have an ordered stream 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.

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

The ordered property is distinct from parallel vs sequential. E.g. if you call stream() on a HashSet the stream will be unordered while calling stream() on a List returns 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).

另请参阅">java.util.stream 包文档.

See also the "Ordering" section of the java.util.stream package documentation.

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

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).

这可能非常微妙,例如Stream.iterate(T,UnaryOperator) 创建有序流,而 Stream.generate(Supplier) 创建一个无序 流.请注意,您在问题中也犯了一个常见错误 forEach 维护顺序.你必须使用 forEachOrdered 如果您想以有保证的顺序处理流的元素.

This can be very subtle, e.g. Stream.iterate(T,UnaryOperator) creates an ordered stream while Stream.generate(Supplier) creates an unordered stream. Note that you also made a common mistake in your question as forEach does not maintain the ordering. You have to use forEachOrdered if you want to process the stream’s elements in a guaranteed order.

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

So if your list in your question is indeed a java.util.List, its stream() method will return an ordered stream and filter will 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<…> 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.

这篇关于如何确保java8流中的处理顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆