如何保持流中元素的顺序

Jok*_*ker 1 java java-8 java-stream

我想使用下面的spliterator()方法保留数组元素的顺序.

但是,当我运行这个程序时,它正在生成4 2 1 3输出.

   public class Test1 {
    public static void main(String[] args) {
        m1().anyMatch(e -> {
            System.out.println(e);
            return false;
        });
    }

    private static LongStream m1() {
    return StreamSupport.longStream(Arrays.spliterator(new long[] { 1, 2, 3, 4 }), true);
    }
}
Run Code Online (Sandbox Code Playgroud)

请检查并告知我这是否可能.

Hol*_*ger 5

您正在请求并行流,因此,您无法获得已定义的处理顺序,因为并行处理和有序处理是一个普遍的矛盾.

如果要按顺序处理元素,则必须同时执行这两个操作,请求顺序流并使用取决于顺序的终端操作:

public static void main(String[] args) {
    m1().filter(e -> {
        System.out.println(e);
        return false;
    }).findFirst();
}

private static LongStream m1() {
    return StreamSupport.longStream(Arrays.spliterator(new long[] { 1, 2, 3, 4 }), false);
}        
Run Code Online (Sandbox Code Playgroud)

但请注意,您应该避免编写依赖于处理顺序的软件.您应该以处理步骤不依赖于处理顺序的方式定义您的任务,即使最终结果可能取决于遭遇顺序.

例如,如果你写

public static void main(String[] args) {
    m1().filter(e -> {
        System.out.println(e);
        return e%2 == 0;
    })
    .findFirst()
    .ifPresent(result -> System.out.println("final result: "+result));
}

private static LongStream m1() {
    // note that you can have it much simpler:
    return LongStream.of(1, 2, 3, 4 ).parallel();
}        
Run Code Online (Sandbox Code Playgroud)

中间输出可以是任意顺序,并且不保证你是否会在输出中看到"3"和"4",但你保证最后输出将是"最终结果:2",因为那是遇到顺序中的第一个匹配元素.另见这里.