Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 forEach with index [duplicate]

Is there a way to build a forEach method in Java 8 that iterates with an index? Ideally I'd like something like this:

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

The best I could do right now is:

int idx = 0;
params.forEach(e -> {
  query.bind(idx, e);
  idx++;
});
like image 497
Josh Stone Avatar asked Oct 07 '22 22:10

Josh Stone


2 Answers

Since you are iterating over an indexable collection (lists, etc.), I presume that you can then just iterate with the indices of the elements:

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

The resulting code is similar to iterating a list with the classic i++-style for loop, except with easier parallelizability (assuming, of course, that concurrent read-only access to params is safe).

like image 217
srborlongan Avatar answered Oct 10 '22 11:10

srborlongan


It works with params if you capture an array with one element, that holds the current index.

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

The above code assumes, that the method forEach iterates through the elements in encounter order. The interface Iterable specifies this behaviour for all classes unless otherwise documented. Apparently it works for all implementations of Iterable from the standard library, and changing this behaviour in the future would break backward-compatibility.

If you are working with Streams instead of Collections/Iterables, you should use forEachOrdered, because forEach can be executed concurrently and the elements can occur in different order. The following code works for both sequential and parallel streams:

int[] idx = { 0 };
params.stream().forEachOrdered(e -> query.bind(idx[0]++, e));
like image 67
nosid Avatar answered Oct 10 '22 10:10

nosid