问题

这个问题在这里已有答案:

  • 是否有一种简洁的方法来迭代Java 8中的索引流? 17个答案

有没有办法在Java 8中构建一个用索引迭代的forEach方法?理想情况下,我喜欢这样的事情:

params.forEach((idx, e) -> query.bind(idx, e));

我现在能做的最好的事情是:

int idx = 0;
params.forEach(e -> {
  query.bind(idx, e);
  idx++;
});

#1 热门回答(116 赞)

由于你正在迭代可索引的集合(列表等),我假设你可以只使用元素的索引进行迭代:

IntStream.range(0, params.size())
  .forEach(idx ->
    query.bind(
      idx,
      params.get(idx)
    )
  )
;

生成的代码类似于使用经典的i-style for循环迭代列表,除了更容易并行化(当然,假设对params的并发只读访问是安全的)。


#2 热门回答(50 赞)

如果你捕获具有一个元素的数组,它将保留当前索引。

int[] idx = { 0 };
params.forEach(e -> query.bind(idx[0]++, e));

上面的代码假定,方法是通过遇到顺序的元素实现的。 interfaceIterables为所有类指定此行为,除非另有说明。显然它适用于标准库中的所有可执行实现,并且将来改变此行为会破坏向后兼容性。

如果你正在使用Streamsinstead ofCollections / Iterables,则应该使用forEachOrdered,因为可以同时执行每个元素并且元素可以以不同的顺序发生。以下代码适用于顺序和并行流:

int[] idx = { 0 };
params.stream().forEachOrdered(e -> query.bind(idx[0]++, e));

#3 热门回答(18 赞)

有一些解决方法,但没有干净/简短/甜蜜的方式与流做这件事,说实话,你可能会更好:

int idx = 0;
for (Param p : params) query.bind(idx++, p);

原文链接