14

Currently (as of Java 6), using Java's enhanced for-loop I do not know of any way to directly access the iterator index short of reverting to the old indexed for-loop or using an outside counter.

Are there plans (or perhaps a current way) to implement this "enhanced enhanced" for-loop where one would be able to access the index of the loop (and even possibly manipulate it)?

As an example where this might be needed, consider(this is from actual production code):

int i = 1;
for (final String action : actions) {
  parameters.set(String.valueOf(i++), action);
}
5
  • 3
    Yeah, I never understood why they called it "enhanced". Calling it the "simplified for-loop" would have been better. Commented Nov 29, 2010 at 21:50
  • 1
    Would be nice to have something like enumerate() in Python, which enables you to iterate over both the index and the element: for i, element in enumerate(list): print i, element Commented Nov 29, 2010 at 22:00
  • OK, so then it seems that the answer is NO on both counts (known plans / jsr for implementation, or a current way to do this). Those who say that it goes against the "philosophy" of its very introduction - I definitly see where your coming from - I just have found myself in situations where I'd like the ability without having to resort to the verbose alternative. Commented Nov 29, 2010 at 22:10
  • The enhanced for loop was introduced in Java 5.0. ;) Commented Nov 30, 2010 at 9:12
  • 1
    as the answer asked, what is the situation that you need an index? could you present the question please? Commented Nov 30, 2010 at 10:47

5 Answers 5

16

Well, like you said, if you must have an index just use a standard for loop, or update a counter manually.

But rethink your question. Why should you need an index in a for (Object o : list) loop?

The whole point of using an enhanced loop is to abstract away the nasty parts of using an index or an iterator.

Most languages today do not give this kind of functionality in loops. Just as an example, the Pythonic way to do this is:

for index, val in enumerate(someList):
    # ....
Sign up to request clarification or add additional context in comments.

Comments

7

No. Use an outside variable.

1 Comment

+1 for being simple and straight forward. Also, for various reasons regarding implementation specific time complexities for Collection.get(i), just adding the counter to the enhanced for loop body is probably the best alternative. As opposed to reverting back to a traditional for(statement;condition;statement) loop structure as previously suggested.
7

Why would they need to provide yet another way of accessing elements by index?

The enhanced for loop was created as a shortcut for when you don't need the index of the element. It streamlined things.

If you still need the index, fall back to a regular for loop. That's one of the reasons they're there.

1 Comment

Well consider iterating over a collection with generics. Its ridiculously long and hard to read when using an Iterator directly. Seems to me like it would be nice to retain the abstraction of the enhanced for-loop while simultaneously being able to access the index (if desired).
3

It's better to keep an outside counter to get the index,but you could do something like this ( it's bit of an overkill for a simple task):

class Enum<T> implements Iterable<Indexer<T>> {
    private int indx;
    private Iterator<T> itr;
    private Indexer<T> indxr = new Indexer<T>();

    private Enum(Iterable<T> iter) {
        this.itr = iter.iterator();
    }

    public static <T> Enum<T> iterate(Iterable<T> iter) {
        return new Enum<T>(iter);
    }

    @Override
    public Iterator<Indexer<T>> iterator() {
        return new AbstractIterator<Indexer<T>>() {
            @Override
            protected Indexer<T> computeNext() {
                if (itr.hasNext()) {
                    indxr.index = indx++;
                    indxr.val = itr.next();
                    return indxr;
                }
                return endOfData();
            }

        };
    }

}

class Indexer<T> {
    public int index;
    public T val;

    @Override
    public String toString() {
        return String.format("[ %d : %s ]", index, val);
    }

For getting index while while iterating:

    List<Integer> list = new ArrayList<Integer>() ;
    list.addAll(Arrays.asList(1, 2, 3, 4, 5,6,55,23,12,24,16));
    for (Indexer<Integer> en : Enum.iterate(list)) 
      System.out.println(en.index+" "+en.val);

Note:The above code has dependency to Guava's AbstractIterator

Comments

1

There isn't way right now unless you keep a counter! I know this is ugly, but java 7 will be better. I don't know why other people are saying we don't need it. Sometimes we need to know what is last member, or odd member, etc.

2 Comments

Did Java 7 address this?
@SamuelEdwinWard No.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.