猿问

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

我有一个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 code

int index = 0;

recs.stream().forEach(rec -> rec.setRecordIndex(index++));

//the compiler complains about the index++ above, says it should be final

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

有没有更好的方法来做到这一点?如果没有,有没有办法修复编译错误并仍然使用流?(而不是循环)


慕沐林林
浏览 133回答 2
2回答

慕容3067478

这可以用 来完成IntStream,我也建议只使用一个Stream:IntStream.range(0, recs.size())&nbsp; &nbsp; .mapToObj(i -> {&nbsp; &nbsp; &nbsp; &nbsp;Rec rec = recs.get(i);&nbsp; &nbsp; &nbsp; &nbsp;rec.setRecordIndex(i);&nbsp; &nbsp; &nbsp; &nbsp;return rec;&nbsp; &nbsp; })&nbsp; &nbsp; .parallel()&nbsp; &nbsp; .forEach(rec -> foo(ProgressInfo, rec));尽管不鼓励修改状态,streams而不是设置index内部状态,mapToObj返回一个新对象可能会更好。例如这样的事情:.mapToObj(i -> {&nbsp; &nbsp;Rec copy = new Rec(recs.get(i)); // copy constructor&nbsp; &nbsp;copy.setRecordIndex(i);&nbsp; &nbsp;return copy;})根据List您使用的实现(ArrayList比LinkedList使用index-access时性能更好),您还可以使用以下代码段。但是peek在生产代码中使用 是有点争议的。IntStream.range(0, recs.size())&nbsp; &nbsp;.peek(i -> recs.get(i).setRecordIndex(i))&nbsp; &nbsp;.parallel()&nbsp; &nbsp;.forEach(i -> foo(ProgressInfo, recs.get(i));

千巷猫影

您可以使用IntStream:IntStream.range(0, recs.size())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.forEach(i -> recs.get(i).setRecordIndex(i));这只是使用从0to的数字流recs.size() - 1,并调用recs.get每个数字。
随时随地看视频慕课网APP

相关分类

Java
我要回答