Is there a way to access an iteration-counter in Java's for-each loop?
No, but you can provide your own counter.
The reason for this is that the for-each loop internally does not have a counter; it is based on the Iterable interface, i.e. it uses an Iterator
to loop through the "collection" - which may not be a collection at all, and may in fact be something not at all based on indexes (such as a linked list).
There is another way.
Given that you write your own Index
class and a static method that returns an Iterable
over instances of this class you can
for (Index<String> each: With.index(stringArray)) { each.value; each.index; ...}
Where the implementation of With.index
is something like
class With { public static <T> Iterable<Index<T>> index(final T[] array) { return new Iterable<Index<T>>() { public Iterator<Index<T>> iterator() { return new Iterator<Index<T>>() { index = 0; public boolean hasNext() { return index < array.size } public Index<T> next() { return new Index(array[index], index++); } ... } } } }}
The easiest solution is to just run your own counter thus:
int i = 0;for (String s : stringArray) { doSomethingWith(s, i); i++;}
The reason for this is because there's no actual guarantee that items in a collection (which that variant of for
iterates over) even have an index, or even have a defined order (some collections may change the order when you add or remove elements).
See for example, the following code:
import java.util.*;public class TestApp { public static void AddAndDump(AbstractSet<String> set, String str) { System.out.println("Adding [" + str + "]"); set.add(str); int i = 0; for(String s : set) { System.out.println(" " + i + ": " + s); i++; } } public static void main(String[] args) { AbstractSet<String> coll = new HashSet<String>(); AddAndDump(coll, "Hello"); AddAndDump(coll, "My"); AddAndDump(coll, "Name"); AddAndDump(coll, "Is"); AddAndDump(coll, "Pax"); }}
When you run that, you can see something like:
Adding [Hello] 0: HelloAdding [My] 0: Hello 1: MyAdding [Name] 0: Hello 1: My 2: NameAdding [Is] 0: Hello 1: Is 2: My 3: NameAdding [Pax] 0: Hello 1: Pax 2: Is 3: My 4: Name
indicating that, rightly so, order is not considered a salient feature of a set.
There are other ways to do it without a manual counter but it's a fair bit of work for dubious benefit.