Is there a way to access an iteration-counter in Java's for-each loop? Is there a way to access an iteration-counter in Java's for-each loop? java java

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.