tan*_*khi 4 java reduce java-8 java-stream
任何人都可以指出正确的方向,因为我无法理解问题。
我正在执行以下方法。
private static void reduce_parallelStream() {
List<String> vals = Arrays.asList("a", "b");
List<String> join = vals.parallelStream().reduce(new ArrayList<String>(),
(List<String> l, String v) -> {
l.add(v);
return l;
}, (a, b) -> {
a.addAll(b);
return a;
}
);
System.out.println(join);
}
Run Code Online (Sandbox Code Playgroud)
它打印
[null,a,null,a]
我不明白为什么它将两个空值放在结果列表中。我希望答案是
[a,b]
因为它是并行流,所以第一个要减少的参数
新的ArrayList()
每个输入值a和b可能会被调用两次。
然后,累加器函数可能会被调用两次,因为它是parallelStream,并在每次调用中传递每个输入“ a和b”以及由种子值提供的列表。因此,将a添加到列表1,将b添加到列表2(反之亦然)。之后,组合器将合并两个列表,但不会发生。
有趣的是,如果我在累加器中放入一条print语句以打印输入值,则输出会更改。所以下面
private static void reduce_parallelStream() {
List<String> vals = Arrays.asList("a", "b");
List<String> join = vals.parallelStream().reduce(new ArrayList<String>(),
(List<String> l, String v) -> {
System.out.printf("l is %s", l);
l.add(v);
System.out.printf("l is %s", l);
return l;
}, (a, b) -> {
a.addAll(b);
return a;
}
);
System.out.println(join);
}
Run Code Online (Sandbox Code Playgroud)
结果输出
l是[] l是[b] l是[b,a] l是[b,a] [b,a,b,a]
谁能解释一下。
使用Collections.synchronizedList()时应使用parallelStream()。因为ArrayList不是线程安全的,并且在同时访问它时会出现意外行为,就像您使用进行操作一样parallelStream()。
我已经修改了您的代码,现在可以正常使用了:
private static void reduce_parallelStream() {
List<String> vals = Arrays.asList("a", "b");
// Use Synchronized List when with parallelStream()
List<String> join = vals.parallelStream().reduce(Collections.synchronizedList(new ArrayList<>()),
(l, v) -> {
l.add(v);
return l;
}, (a, b) -> a // don't use addAll() here to multiplicate the output like [a, b, a, b]
);
System.out.println(join);
}
Run Code Online (Sandbox Code Playgroud)
输出:
有时您会得到以下输出:
[a, b]
Run Code Online (Sandbox Code Playgroud)
有时这个:
[b, a]
Run Code Online (Sandbox Code Playgroud)
这样做的原因是它是a,parallelStream()所以您不能确定执行顺序。
| 归档时间: |
|
| 查看次数: |
117 次 |
| 最近记录: |