在Java的for-each循环中有办法吗
for(String s : stringArray) {
doSomethingWith(s);
}
找出循环已经被处理的频率?
除了使用老的和众所周知的for(int i=0;I <边界;i++) - loop,是构造
int i = 0;
for(String s : stringArray) {
doSomethingWith(s);
i++;
}
在for-each循环中有这样一个计数器的唯一方法是什么?
在Java的for-each循环中有办法吗
for(String s : stringArray) {
doSomethingWith(s);
}
找出循环已经被处理的频率?
除了使用老的和众所周知的for(int i=0;I <边界;i++) - loop,是构造
int i = 0;
for(String s : stringArray) {
doSomethingWith(s);
i++;
}
在for-each循环中有这样一个计数器的唯一方法是什么?
当前回答
虽然有很多其他的方法可以达到同样的效果,但我还是将我的方法分享给一些不满意的用户。我正在使用Java 8 IntStream特性。
1. 数组
Object[] obj = {1,2,3,4,5,6,7};
IntStream.range(0, obj.length).forEach(index-> {
System.out.println("index: " + index);
System.out.println("value: " + obj[index]);
});
2. 列表
List<String> strings = new ArrayList<String>();
Collections.addAll(strings,"A","B","C","D");
IntStream.range(0, strings.size()).forEach(index-> {
System.out.println("index: " + index);
System.out.println("value: " + strings.get(index));
});
其他回答
如果你在for-each循环中需要一个计数器,你就必须数自己。据我所知,没有内置的计数器。
还有另一种方法。
如果您编写了自己的Index类和一个静态方法,该方法在该类的实例上返回Iterable,那么您可以
for (Index<String> each: With.index(stringArray)) {
each.value;
each.index;
...
}
其中实现With。索引是这样的
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++); }
...
}
}
}
}
}
最简单的解决方法是运行你自己的计数器:
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
这表明,顺序不被认为是一个集合的显著特征。
除了手动计数器,还有其他方法可以做到这一点,但这是一项相当大的工作,而且效益不确定。
Java 8引入了Iterable#forEach() / Map#forEach()方法,与“经典的”for-each循环相比,该方法对于许多Collection / Map实现更有效。但是,在这种情况下也不提供索引。这里的技巧是在lambda表达式之外使用AtomicInteger。注意:lambda表达式中使用的变量必须有效为final,这就是为什么我们不能使用普通int类型。
final AtomicInteger indexHolder = new AtomicInteger();
map.forEach((k, v) -> {
final int index = indexHolder.getAndIncrement();
// use the index
});
对于偶尔需要索引的情况,比如在catch子句中,我有时会使用indexOf。
for(String s : stringArray) {
try {
doSomethingWith(s);
} catch (Exception e) {
LOGGER.warn("Had some kind of problem with string " +
stringArray.indexOf(s) + ": " + s, e);
}
}