Mas*_*aza 1 java parallel-processing java-8 parallel.foreach
我正在尝试将迭代 ArrayList 的普通 for 循环转换为并行循环。我遇到了parallelStream.forEach() 和parallelStream().collect(Collectors.toList()) 的概念。但不清楚如何转换。下面是普通 for 循环的示例代码:
public List<FinPlan> getFinPlanList() {
List<FinPlan> newList = new ArrayList<>();
// get list of string
List<String> finPlanIdsList = finPlanSearchRequest.getFinPlanIds();
// iterate list and add element to new list
for(String planId: finPlanIdsList) {
newList.add(retrieveFinPlan(planId));
}
return newList;
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用以下代码,但它给了我错误“newList 应该是最终的”。
finPlanIdsList.parallelStream().forEach( planId -> {
newList.add(retrieveFinPlan(planId));
});
Run Code Online (Sandbox Code Playgroud)
那么,主要问题是如何将上面的普通循环转换为parallelStream.forEach()和parallelStream().collect()?
当前版本中发生编译错误的原因是 lambda 表达式不允许使用final在创建 lambda 时既不是最终的也不是有效的局部变量。
你可以尝试这样修复它:
final List<FinPlan> = new ArrayList<>();
...
finPlanIdsList.parallelStream().forEach( planId -> {
newList.add(retrieveFinPlan(planId));
});
Run Code Online (Sandbox Code Playgroud)
...但这有一个更微妙的缺陷,即代码不是线程安全的。该newList对象可能会从不同的线程更新......并且ArrayList不是线程安全的类。
正确的解决方案是这样的:
List<FinPlan> newList =
finPlanIdsList.parallelStream()
.map(planId -> retrieveFinPlan(planId))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
如果结果必须为ArrayList,则可以将Collectors.toList()表达式替换为Collections.toCollection(ArrayList::new)。
一般来说,流依赖副作用是一个坏主意。在某些情况下,你会侥幸逃脱惩罚。在其他方面……不。
| 归档时间: |
|
| 查看次数: |
2582 次 |
| 最近记录: |