Java 如何保持流中元素的顺序

Java 如何保持流中元素的顺序,java,java-8,java-stream,Java,Java 8,Java Stream,我想使用below spliterator()方法保留数组元素的顺序 但是,当我运行这个程序时,它会产生4 2 1 3作为输出 public class Test1 { public static void main(String[] args) { m1().anyMatch(e -> { System.out.println(e); return false; }); } p

我想使用below 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);
    }
}

请检查并让我知道这是否可行。

当您正在创建并行流时(第二个参数=
true

longStream(Arrays.spliterator(新的long[]{1,2,3,4}),true)

您无法获得有序访问权限。如果您创建一个顺序流(将第二个参数从
true
更改为
false
),您应该会得到您想要的。

您使用的是
anyMatch
,它一开始并没有保留顺序,所以这几乎是意料之中的。如果要获取第一个元素,请使用
findFirst

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

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

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”,因为这是顺序中的第一个匹配元素。另请参见。

顺序不依赖于并行或顺序,它是定义顺序的操作…但即使这种方法在流式处理时也不会保留顺序。我尝试了
StreamSupport.longStream(Arrays.spliterator(新的long[]{1,2,3,4}),true)。filter(e->{System.out.println(e);return false;})。findFirst()
并且元素以随机顺序打印。我认为是平行流导致了这种行为。findFirst()必须找到任何元素,然后确定它是否是流中的第一个元素。@Madjosz终端操作的顺序是有保证的,即尝试使用
forEachOrdered
或将元素收集到
列表中并打印这些元素。处理顺序(在您的
过滤器中
)未指定为存在。这是正确的,当然,如果使用终端操作,原始顺序将保留。如果并行流化,然后按顺序收集数据,可能会影响性能。我不知道为什么询问者希望在并行流中操作时保持秩序。这将是一个非常大的开销,因为您需要一些管理进程,以正确的顺序将元素提供给多个线程。@Madjosz:在并行流中保留处理顺序将不仅仅是一个大开销,它通常与并行处理相矛盾。如果处理步骤有顺序,则它们不是并行的。