带索引的Java8foreach

带索引的Java8foreach,java,for-loop,foreach,java-8,Java,For Loop,Foreach,Java 8,有没有办法在Java8中构建一个使用索引进行迭代的forEach方法?理想情况下,我想要这样的东西: params.forEach((idx, e) -> query.bind(idx, e)); 我现在能做的最好的事情是: int idx = 0; params.forEach(e -> { query.bind(idx, e); idx++; }); 有一些变通方法,但没有干净/短/甜美的方法来处理流,老实说,您可能会更好地使用: int idx = 0; for (

有没有办法在Java8中构建一个使用索引进行迭代的
forEach
方法?理想情况下,我想要这样的东西:

params.forEach((idx, e) -> query.bind(idx, e));
我现在能做的最好的事情是:

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

有一些变通方法,但没有干净/短/甜美的方法来处理流,老实说,您可能会更好地使用:

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

for (int idx = 0; idx < params.size(); idx++) query.bind(idx, params.get(idx));
for(intidx=0;idx
如果捕获一个包含当前索引的元素的数组,则它与params一起工作

int[] idx = { 0 };
params.forEach(e -> query.bind(idx[0]++, e));
上面的代码假设forEach方法按遇到顺序遍历元素。接口Iterable为所有类指定此行为,除非另有说明。显然,它适用于标准库中Iterable的所有实现,将来改变这种行为将破坏向后兼容性

如果您使用的是流而不是集合/Iterables,那么应该使用forEachOrdered,因为forEach可以并发执行,并且元素可以以不同的顺序出现。以下代码适用于顺序流和并行流:

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

由于您在可索引集合(列表等)上进行迭代,因此我假定您可以使用元素的索引进行迭代:

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

生成的代码类似于使用经典的i++样式for循环迭代列表,只是更易于并行化(当然,假设对参数的并发只读访问是安全的)。

如果合并increment
query.bind(idx++,e)但这就是我所能想到的,所以,您不应该在该lambda中修改
idx
。@SotiriosDelimanolis它实际上是编译的,如果
idx
是一个实例变量或什么的话。如果您发布的代码位于方法/构造函数主体中,则不会出现此问题。@assylias我投票重新打开此问题,因为我不认为它与链接问题完全相同。链接问题的海报希望在流处理的中间获得索引,而这个问题的焦点只是获得(终端)<代码>前缀方法中的索引(基本上取代了手工索引的传统for循环)。我认为我们不应该阻止在这里添加更多的答案。事实上,我想提供一个适合这个问题的答案,但不适合链接的问题。与其使用
int[]
数组,不如使用一个。这也将确保如果元素出现无序,我们至少会为每个元素获得一个唯一的索引。@BrettRyan:我不同意
AtomicInteger
表达了错误的意图,效率较低,并且在这种情况下保证了顺序执行。ApacheLang库中的MutableInt不是很好吗?如果使用forEachOrdered,它不需要是同步结构,对吗?@Skychan:在这种情况下没有帮助,因为它缺少一些操作。特别是像@nosid这样的东西,我不认为使用
int[]
AtomicInteger
更能揭示意图。如果性能是一个问题,那么for循环可能更好,因为它避免了
机制,这可能使高度优化的
原子类*
相形见绌。@Tomercan您可以:将索引映射到首选顺序,如果所述顺序可以表示为函数(要反向迭代参数,请使用IntStream.range(0,params.size()).map(i->params.size()(params.size())如果要以斐波那契顺序迭代参数的子集。唯一需要考虑的是,当以这种方式迭代链接列表时,将使用O(nˆ2)而不是O(n)再一次,Java和它糟糕的简单语法。Java什么时候会提供一个更简单的选择..我想知道这个答案是否比
int[]idx={0};params.forEach(e->query.bind(idx[0]++,e));
?晚了,但完全同意。当需要索引时,普通的for循环就足够了。@Vortex和更可读性。