Java流处理顺序

时间:2016-07-08 08:36:20

标签: java java-8 java-stream

我有以下内容:

LinkedList<Integer> ints = new LinkedList();
//fill it with some ints
Stream<Integer> stream = ints.stream();
//process the stream in some way

我的问题是,是否保证流的处理顺序是基础LinkedList的顺序?我读了documentation,但没有关于订购的任何信息。

就我而言,维护订单至关重要。

2 个答案:

答案 0 :(得分:2)

来自documentation

  

Streams可能有也可能没有已定义的遭遇顺序。是否   一个流有一个遭遇顺序取决于源和   中间操作。某些流源(例如List或   数组)本质上是有序的,而其他的(如HashSet)   不是。某些中间操作(例如sorted())可能会强制执行   在其他无序流上遇到订单,其他人可能会   渲染无序的有序流,例如BaseStream.unordered()。   此外,一些终端操作可以忽略遭遇顺序,例如   的forEach()。

     

如果订购了流,则大多数操作都被限制为可以进行操作   他们遭遇顺序中的元素;如果流的来源是   列表包含[1,2,3],然后执行map的结果(x - &gt; x * 2)   必须是[2,4,6]。但是,如果源没有定义的遭遇   顺序,那么值[2,4,6]的任何排列都是有效的   结果

     

对于顺序流,是否存在遭遇订单   不影响表现,只影响决定论。如果订购了流,   在相同的流程上重复执行相同的流管道   源将产生相同的结果;如果没有订购,   重复执行可能会产生不同的结果。

     

对于并行流,有时可以放宽排序约束   实现更高效的执行...

另外,正如您所说,处理顺序对您很重要,请参阅here

  

流管道结果可能是不确定的或不正确的   流操作的行为参数是有状态的......

     

最好的方法是避免有状态的行为参数流式传输   完全运作;通常有一种重组流的方法   管道,以避免有状态。

另请参阅此问题的答案:How to ensure order of processing in java8 streams?

简而言之,如果您使用顺序流(在一个线程中执行的流),并且您对forEach()等操作非常谨慎,则看起来您可以保留顺序。然而,这可能不是一个好主意。

答案 1 :(得分:1)

取决于您应用于流的处理...尤其是使用parallel()

import java.util.LinkedList;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class Streaming {

    public static void main(String[] args) {
        LinkedList<Integer> ints = new LinkedList();
        for(int i = 0 ; i < 100; i++) {
            ints.add(i);
        }
        Stream<Integer> stream = ints.stream();
        // will not be ordered
        stream.parallel().forEach(new Consumer<Integer>() {

            @Override
            public void accept(Integer t) {
                System.out.println(t);
            }

        });

        stream = ints.stream();
        // will be ordered
        stream.parallel().forEachOrdered(new Consumer<Integer>() {

            @Override
            public void accept(Integer t) {
                System.out.println(t);
            }

        });
    }
}