ama*_*ish 4 java java-8 java-stream
我正在阅读关于java流API和我从这里遇到以下声明
无论流是以串行还是并行方式执行,forOachOrdered操作都按流指定的顺序处理元素.但是,当并行执行流时,映射操作会处理由Java运行时和编译器指定的流的元素.因此,lambda表达式的顺序为e - > {parallelStorage.add(e); 返回e; 向List添加元素parallelStorage每次运行代码时都会有所不同.对于确定性和可预测的结果,请确保流操作中的lambda表达式参数不具有状态.
我测试了我的以下代码,它实际上如上所述.
public class mapordering {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> serialStorage = new ArrayList<>();
System.out.println("Serial stream:");
int j=0;
List<String> listOfIntegers = new ArrayList() ;
for(int i=0;i<10;i++)listOfIntegers.add(String.valueOf(i));
listOfIntegers.stream().parallel() .map(e -> { serialStorage.add(e.concat(String.valueOf(j))); return e; }).forEachOrdered(k->System.out.println(k));;
/*
// Don't do this! It uses a stateful lambda expression.
.map(e -> { serialStorage.add(e); return e; })*/
for(String s:serialStorage)System.out.println(s);
}
}
Run Code Online (Sandbox Code Playgroud)
产量
串行流:0 1 2 3 4 5 6 7 8 9 null null 80 90 50 40 30 00
问题:
你很幸运地看到它serialStorage具有你认为它将具有的所有元素,毕竟你是从多个线程添加多个元素到非线程安全的集合ArrayList.您可以很容易地看到nulls或a List没有所有元素.但即使你添加一个List线程安全的东西 - 绝对没有你可以依赖的顺序.
这在副作用的文档中明确提到,中间操作应该是无副作用的.
基本上有两种排序:处理订单(中间操作)和遭遇订单.保留最后一个(如果它有一个开头,流中间操作不会破坏它 - 例如unordered,sorted).
未指定处理顺序,这意味着所有中间操作都将以他们想要的顺序处理元素.遇到订单(您从终端操作中看到的订单)将保留初始订单.
但即使终端操作也不必保留初始订单,例如forEachvs forEachOrdered或收集到的时候Set; 当然阅读文档,它通常清楚地说明这方面.
| 归档时间: |
|
| 查看次数: |
138 次 |
| 最近记录: |