如何保持流中元素的顺序

时间:2017-07-03 09:52:10

标签: 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);
    }
}

请检查并告诉我这是否可能。

3 个答案:

答案 0 :(得分: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);
}        

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

,例如,如果你写

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();
}        

中间输出可能是任意顺序,并且无法保证输出中是否会显示“3”和“4”,但您保证最后输出为“最终结果:2”,因为这是遇到订单中的第一个匹配元素。另请参阅here

答案 1 :(得分:2)

嗯,你使用的anyMatch首先没有保留顺序,所以非常期待。如果你想获得第一个元素,例如使用findFirst

答案 2 :(得分:1)

在创建并行流时(第二个参数= true StreamSupport.longStream(Arrays.spliterator(new long[] { 1, 2, 3, 4 }), true) 你没有得到有序的访问权限。如果您创建顺序流(将第二个参数从true更改为false),您应该得到您想要的内容。