Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java8中,一个顺序有序的流是否能保证按顺序执行操作?_Java_Java Stream - Fatal编程技术网

在Java8中,一个顺序有序的流是否能保证按顺序执行操作?

在Java8中,一个顺序有序的流是否能保证按顺序执行操作?,java,java-stream,Java,Java Stream,是否有任何保证在顺序和有序流上的操作以遭遇顺序处理 我的意思是,如果我有这样的代码: IntStream.range(0, 5) .map(i -> { myFunction(i); return i * 2; }) .boxed() .collect(toList()); 是否可以保证它将按照生成范围的遭遇顺序执行myFunction()调用 我发现课堂上明确指出: 对

是否有任何保证在顺序有序流上的操作以遭遇顺序处理

我的意思是,如果我有这样的代码:

IntStream.range(0, 5)
        .map(i -> {
            myFunction(i);
            return i * 2;
         })
         .boxed()
         .collect(toList());
是否可以保证它将按照生成范围的遭遇顺序执行myFunction()调用

我发现课堂上明确指出:

对于顺序流管道,如果管道源具有定义的相遇顺序,则所有操作都将按照管道源的相遇顺序执行

但在最后,这条线被删除了。现在只讨论选定方法的遭遇顺序。副作用段中的说明:

即使管道被约束以生成与流源的相遇顺序一致的结果(例如,
IntStream.range(0,5).parallel().map(x->x*2).toArray()
必须生成
[0,2,4,6,8]
),不保证映射器函数应用于单个元素的顺序,也不保证在哪个线程中为给定元素执行任何行为参数

但是它没有提到顺序流,这个例子是针对并行流的(我的理解是,顺序流和并行流都是如此,但这是我不确定的部分)

另一方面,它在该节中还指出:

如果一个流是有序的,那么大多数操作都会被约束为按照元素的遭遇顺序对元素进行操作;如果流的源是包含
[1,2,3]
列表,则执行
映射(x->x*2)
的结果必须是
[2,4,6]
。但是,如果源没有定义遭遇顺序,则值的任何排列
[2,4,6]
都将是有效的结果


但这次是从“对元素进行操作”开始的,但这个例子是关于结果流的,所以我不确定他们是否考虑了副作用,副作用才是这个问题真正的意义所在。

我认为我们可以从这个明确的句子被删除的事实中学到很多。这个问题似乎与这个问题密切相关。基本上说,尽管在序列流上调用
forEach
时,流的当前实现没有忽略顺序的场景,
forEach
可以自由忽略偶遇顺序,即使对于每个规范的序列流也是如此

现在考虑以下部分:

为了执行计算,将流操作组合到流管道中。流管道由源(可能是数组、集合、生成器函数、I/O通道等)、零个或多个中间操作(将流转换为另一个流,如
过滤器(谓词)
)和终端操作(产生结果或副作用,如
计数()
forEach(消费者)
)。溪流是懒惰的;仅当终端操作启动时才对源数据执行计算,并且仅在需要时使用源元素

由于终端操作决定是否需要元素以及元素在遭遇顺序中是否需要,因此终端操作忽略遭遇顺序的自由也意味着以任意顺序消费、处理元素

请注意,不仅forEach
可以做到这一点。
收集器
能够报告特征,例如
收集器。toSet()
不取决于遭遇顺序。很明显,像
count()
这样的操作也不依赖于Java 9中的顺序,它甚至可以在不进行任何元素处理的情况下返回。想想
IntStream#sum()
作为另一个例子

在过去,实现过于热衷于向上游传播无序特性,看看终端操作对
跳过
步骤的结果有何影响,这就是当前实现不愿意进行此类优化以避免类似错误的原因,但这并不排除重新出现这种优化,然后在实施时更加小心


因此,目前很难想象一个实现如何能够从利用顺序流中无序求值的自由中获得性能优势,但是,正如
forEach
相关问题中所述,这并不意味着任何保证。

这是否回答了您的问题?我把问题扩展到了排序部分,这听起来好像与副作用部分相矛盾。也许这个@Hulk:summing
int
s是否会溢出并不取决于元素的顺序。对于所有
int
值,
a+b+c
的结果与
c+b+a
b+c+a
等的结果相同,即使发生溢出。这就是为什么我选择了
IntStream#sum()
而不是
DoubleStream#sum()
,其中顺序确实有所不同(尽管
DoubleStream#sum()
的文档明确指出,添加顺序将是未定义的).我想了一会儿后得出了同样的结论-这就是为什么我已经删除了我的评论。抱歉造成任何混乱;)因此,目前很难想象一个实现如何能够从利用顺序流中无序计算的自由度中获得性能优势-
。sorted()。findAny()
可以消除排序。如果无序可以传播回源拆分器(它不能),那么一些数据结构遍历也可以优化。@8472井,消除排序是唯一的优化