为了账号安全,请及时绑定邮箱和手机立即绑定

我如何为要并行处理的 java List 中的每个项目添加索引

我如何为要并行处理的 java List 中的每个项目添加索引

慕沐林林 2021-06-08 17:49:25
我有一个Rec's的列表,我想通过调用一些方法来并行处理它们foo()。foo()可能会将 some 标记Rec为错误,最后所有错误记录都通过它们的索引位置报告(例如“rec 12 is not valid”)。所以我想要么将每个 Rec 的索引位置传递给 foo(),要么在调用 foo 之前将索引设置到每个 Rec 中。我试图做的(如下所示)是首先,按顺序将索引设置为每个 Rec,然后在每个 Rec 上并行调用 foo。有一个更好的方法吗?List<Rec> recs;class Rec {    private int recordIndex;    public void setRecordIndex( int index) { recordIndex = index; }    //more memebers and getter to the above...}//somewhere in the codeint index = 0;recs.stream().forEach(rec -> rec.setRecordIndex(index++));//the compiler complains about the index++ above, says it should be finalrec.parallelStream().forEach(rec -> foo(ProgressInfo, rec));有没有更好的方法来做到这一点?如果没有,有没有办法修复编译错误并仍然使用流?(而不是循环)
查看完整描述

2 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

这可以用 来完成IntStream,我也建议只使用一个Stream:


IntStream.range(0, recs.size())

    .mapToObj(i -> {

       Rec rec = recs.get(i);

       rec.setRecordIndex(i);

       return rec;

    })

    .parallel()

    .forEach(rec -> foo(ProgressInfo, rec));

尽管不鼓励修改状态,streams而不是设置index内部状态,mapToObj返回一个新对象可能会更好。例如这样的事情:


.mapToObj(i -> {

   Rec copy = new Rec(recs.get(i)); // copy constructor

   copy.setRecordIndex(i);

   return copy;

})

根据List您使用的实现(ArrayList比LinkedList使用index-access时性能更好),您还可以使用以下代码段。但是peek在生产代码中使用 是有点争议的。


IntStream.range(0, recs.size())

   .peek(i -> recs.get(i).setRecordIndex(i))

   .parallel()

   .forEach(i -> foo(ProgressInfo, recs.get(i));


查看完整回答
反对 回复 2021-06-10
?
千巷猫影

TA贡献1829条经验 获得超7个赞

您可以使用IntStream:


IntStream.range(0, recs.size())

         .forEach(i -> recs.get(i).setRecordIndex(i));

这只是使用从0to的数字流recs.size() - 1,并调用recs.get每个数字。


查看完整回答
反对 回复 2021-06-10
  • 2 回答
  • 0 关注
  • 132 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信