有没有办法在Java的for-each循环中访问迭代计数器?

问题

在Java的for-each循环中是否有一种方法

for(String s : stringArray) {
  doSomethingWith(s);
}

找出循环已经处理的频率?

除了使用旧的和众所周知的for(int i=0; i < boundary; i++)循环之外,还有构造

int i = 0;
for(String s : stringArray) {
  doSomethingWith(s);
  i++;
}

在for-each循环中使用这种计数器的唯一方法是什么?


#1 热门回答(161 赞)

不,但你可以提供自己的柜台。

这样做的原因是for-each循环内部没有计数器;它基于Iterable接口,即它使用anIterator循环遍历"集合" - 它可能根本不是集合,实际上可能根本不是基于索引(例如链表)。


#2 热门回答(55 赞)

还有另一种方式。

鉴于你编写自己的Index类和一个返回此类实例的Iterable的静态方法,你可以

for (Index<String> each: With.index(stringArray)) {
    each.value;
    each.index;
    ...
}

那里执行With.index就好

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++); }
                    ...
                }
            }
        }
    }
}

#3 热门回答(34 赞)

最简单的解决方案就是运行自己的计数器:

int i = 0;
for (String s : stringArray) {
    doSomethingWith(s, i);
    i++;
}

这样做的原因是因为没有实际保证集合中的项目(即for的变体)甚至具有索引,甚至具有确定的顺序(某些集合可能会在添加或删除元素时更改顺序)。

例如,参见以下代码:

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");
  }
}

当你运行它时,你可以看到类似的东西:

Adding [Hello]
   0: Hello
Adding [My]
   0: Hello
   1: My
Adding [Name]
   0: Hello
   1: My
   2: Name
Adding [Is]
   0: Hello
   1: Is
   2: My
   3: Name
Adding [Pax]
   0: Hello
   1: Pax
   2: Is
   3: My
   4: Name

表明正确的顺序不被认为是集合的显着特征。

还有其他方法可以在没有手动计数器的情况下完成它,但这对于可疑的益处来说是相当多的工作。