java.util.stream
的{{3}}声明如下:
有状态lambda的一个例子是
map()
中的参数:Set<Integer> seen = Collections.synchronizedSet(new HashSet<>()); stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })...
这里,如果映射操作是并行执行的,由于线程调度的差异,相同输入的结果可能因运行而异,而对于无状态lambda表达式,结果将始终相同。
我不明白为什么这不会产生一致的结果,因为该集合是同步的,并且一次只能处理一个元素。您是否可以通过演示结果因并行化而变化的方式完成上述示例?
答案 0 :(得分:3)
List<Integer> numbers = // fill it in with [1, 3, 3, 5]
List<Integer> collected = numbers.stream().parallel().map(...).collect(Collectors.toList());
collected
可以包含[0,0,3,0]或[0,3,0,0],具体取决于首先处理的中间两个元素中的哪一个。
答案 1 :(得分:2)
我不确定这是否属于有状态本身(如果不是我只会删除它),而是依赖于在map
内有状态的任何等等很糟糕。
int[] arr = new int[3];
Stream.of(1, 2, 3)
.map(i -> {
arr[i] = i + 5;
return i * 2;
})
.count();
System.out.println(Arrays.toString(arr));
在jdk-9中,这将生成一个仅包含零的数组,因为没有更改Stream大小(flatmap
或filter
)的操作,因此永远不会执行map
。