foreach 循环

foreach循环权威总结

-* 原文地址 http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html*

集合迭代的代码实现往往非常臃肿。考虑下面这个例子,它遍历定时器任务并取消它们:

void cancelAll(Collection<TimerTask> c) {
    for (Iterator<TimerTask> i = c.iterator(); i.hasNext(); )
        i.next().cancel();
}

这个迭代器的使用非常繁琐也容易导致错误。因为迭代器在循环中出现了3次,后面两次都可能出错。而for-each循环解决了这些问题:

void cancelAll(Collection<TimerTask> c) {
    for (TimerTask t : c)
        t.cancel();
}

其中冒号读作“in”。这个循环读作“for each TimerTask t in c.”for-each循环和泛型完美结合,此时我们不需要声明迭代器,因此也不需要为它提供泛型定义(实际上编译器为我们实现了这些)。所以它不但提供了类型安全,也去掉了复杂的语法 。

下面是嵌套循环中容易出现的另一个错误:

List suits = ...;
List ranks = ...;
List sortedDeck = new ArrayList();

// BROKEN - throws NoSuchElementException!
for (Iterator i = suits.iterator(); i.hasNext(); )
    for (Iterator j = ranks.iterator(); j.hasNext(); )
        sortedDeck.add(new Card(i.next(), j.next()));

如果你没有发现这个bug请不要灰心,许多专家级的程序员也会时不时犯这个错误。仔细检查会发现suits的next方法被调用了太多次。要解决这个问题可以采用下列方法:

// Fixed, though a bit ugly
for (Iterator i = suits.iterator(); i.hasNext(); ) {
    Suit suit = (Suit) i.next();
    for (Iterator j = ranks.iterator(); j.hasNext(); )
        sortedDeck.add(new Card(suit, j.next()));
}

那这和for-each循环有什么关系呢?实时上它可以完美解决这个问题:

for (Suit suit : suits)
    for (Rank rank : ranks)
        sortedDeck.add(new Card(suit, rank));

for-each对数组同样有效:

// Returns the sum of the elements of a
int sum(int[] a) {
    int result = 0;
    for (int i : a)
        result += i;
    return result;
}

那么我们什么时候采用for-each循环呢?实际上我们应该尽可能使用它。它可以让代码更加完美。但是它也有自己的缺点。因为for-each隐藏了迭代器,因此我们无法调用remove方法以删除元素,也无法在循环中替换元素。同时它也不适合并行遍历多个集合。
事实上for-each的设计者们精心考虑过这些问题,目前的for-each设计是一个简洁易用而且足以覆盖大多数情况的解决方案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值