Java中的foreach循环如何跳过第一次迭代?

77

有没有一种优雅的方式在Java5的foreach循环中跳过第一次迭代?

示例伪代码:

for ( Car car : cars ) {     
   //skip if first, do work for rest
   .
   .
}

5
作为参考,Java5 已经不是“新的”版本已经有5-6年的时间了。 - cHao
我怀疑这是foreach循环明确不打算处理的事情。 - Owen
1
我应该说“更新的”:P - Amir Afghani
11个回答

85

使用Java 8的新Stream API,代码会变得非常优雅。只需使用skip()方法:

cars.stream().skip(1) // and then operations on remaining cars

81

我不会称之为优雅,但或许比使用“first”布尔值更好:

for ( Car car : cars.subList( 1, cars.size() ) )
{
   .
   .
}

除此之外,可能没有更优雅的方法。


所有有序集合类型和数组都有“子集”类型命令吗? - RHSeeger
1
@RHSeeger 不,我不这么认为。我的意思是,使列表成为列表的唯一因素就是它有序,那么你如何指定无序集合的子集边界呢?我想你可以跳过迭代器的第一个迭代,但不能保证你总是跳过相同的第一个元素。 - Sean Adkinson
还有一个右括号 :) - Bakudan

29
for (Car car : cars)
{
   if (car == cars[0]) continue;
   ...
}

对我来说足够优雅。


这样对我来说更清晰...假定在大列表上速度也应该快很多吧? - noelicus
2
除非一个元素被重复,但+1是为了更加优雅。 - borjab
12
呃,每次循环都加一个不必要的条件? 不需要。 - Andrew

28

20

SeanA的代码有一个小错误:sublist的第二个参数被视为是一个不包含在内的索引,因此我们可以这样写:

for (Car car : cars.subList(1, cars.size()) {
   ...
}

(我似乎无法在回答中评论,因此新回答。我需要特定的声望才能这样做吗?)  


3
现在你应该可以评论了。 - Ishtar

7

我来晚了,但你可以使用一个辅助方法,类似于:

public static <T> Iterable<T> skipFirst(final Iterable<T> c) {
    return new Iterable<T>() {
        @Override public Iterator<T> iterator() {
            Iterator<T> i = c.iterator();
            i.next();
            return i;
        }
    };
}

然后像这样使用它:

public static void main(String[] args) {
    Collection<Integer> c = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    for (Integer n : skipFirst(c)) {
        System.out.println(n);
    }
}

略过“n”个元素的推广留给读者作为练习 :)


编辑:仔细检查后,我发现Guava在这里有一个Iterables.skip(...)方法。


3

虽然不太优雅,但能与迭代器一起工作

Iterator<XXXXX> rows = array.iterator();
if (rows.hasNext()){
    rows.next();
}
for (; rows.hasNext();) {
    XXXXX row = (XXXXX) rows.next();
}

3

我不是一个Java专家,但你可以使用这个:

for ( Car car : cars.tail() ) 这是从 java.util 通过 Groovy JDK 引入的。


它是否假定汽车是一个列表? - Piyush Mattoo

2

这种方法可能不够优雅,但可以在 for 循环外初始化一个整数变量,并在循环内的每次迭代中增加它。只有当计数器大于0时,您的程序才会执行。

int counter = 0;
for ( Car car : cars ) {
    //skip if first, do work for rest
    if(counter>0){
        //do something
    }
    counter++;
}

1

优雅?并不是真的。你需要检查/设置一个布尔值。

对于每个循环来说,实际上是使用迭代器的花哨语法。最好在开始循环之前使用迭代器并进行推进。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接