如何将普通的for循环转换为java中的并行流



我正试图将正常的for循环迭代数组列表转换为并行列表。我遇到了parallelStream. foreach()和parallelStream().collect(collections . 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;
}

我尝试了下面的代码,但它给我的错误是"newList应该是final"

finPlanIdsList.parallelStream().forEach( planId -> {
newList.add(retrieveFinPlan(planId));
});
所以,主要的问题是如何将上面的普通循环转换为parallelStream. foreach()和parallelStream().collect() ?

当前版本的编译错误正在发生,因为lambda表达式在创建lambda时不允许使用既不是final也不是有效final的局部变量。

你可以试着这样修改:

final List<FinPlan> = new ArrayList<>();
...
finPlanIdsList.parallelStream().forEach( planId -> {
newList.add(retrieveFinPlan(planId));
});

…但这有一个更微妙的缺陷,即代码不是线程安全的。newList对象可能会从不同的线程更新…ArrayList不是一个线程安全的类。

正确的解决方法是:

List<FinPlan> newList = 
finPlanIdsList.parallelStream()
.map(planId -> retrieveFinPlan(planId))
.collect(Collectors.toList());

如果结果必须是ArrayList,则可以将Collectors.toList()表达式替换为Collections.toCollection(ArrayList::new)

一般来说,流依赖于副作用是一个坏主意。在某些情况下,你会侥幸逃脱。在其他国家……没有。

你的方法定义似乎是不正确的,因为getFinPlanList返回一个FinPlan而不是List

此外,您不能在lambda表达式中使用非有效final的局部变量。因此它不会编译。您可以尝试使用以下命令来生成列表。注意,一旦应用parallelstream,对象的处理顺序就不能保证了。

return finPlanIdsList.parallelStream().map(finPlanId->retrieveFinPlan(finPlanId)).collect(Collectors.toList());

相关内容

  • 没有找到相关文章

最新更新