JDK1.5中新的语言特征——For-Each 循环[转]

在先前的版本中,迭代一个集合的代码显得有点丑陋。


考虑下面的函数,它接受一个包含TimerTask 的集合,然后将那些 TimeTask 删去(concel)。

void cancelAll(Collection c) {
     for (Iterator i = c.iterator(); i.hasNext(); )
         i.next().cancel();
}
Iterator 简直可以叫混乱( clutter)。更糟的是,它还是产生错误的温床。 Iterator 变量在每个循环中出现三次:这就有两个机会出错。 For-each 句式除去了混乱和产生错误的温床。下面就是前面的例子用 for-each句式改写后的样子:
void cancelAll(Collection c) {
     for (TimerTask t : c)
         t.cancel();
}

冒号(:)读为"in."。上面的循环读作"for each TimerTask t in c." 如你所见,for-each 句式与泛型完美地结合了起来。它在除去残存的混乱的同时,保留了所有的类型安全性。因为你不用声明Iterator 变量,你不用为它提供一个泛型声明。(编译器在背后为你做了这些事,但你不需要对此有顾虑。)
下面是人们通常会犯的一个错误,当他们试图对两个集合进行嵌套的迭代的时候:
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()));
你能找到臭虫吗?如果不能,也别介怀。很多编程老手都曾犯过这样的错误。问题就在于:在外部集合上(suits,next 方法被调用了太多次了,在内部循环中,内部集合和外部集合都调用了next,这是错的。想要改正这个错误,你不得不在外部循环中添加一个变量来保存该suit
// 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 句式也适用于数组,这种情况下它隐藏的不是iterator 而是下标变量。下面的函数返回int数组中所有值的和:
// 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 循环呢?任何时候。它真的美化了你的代码。不幸的是,你不能在任何地方使用它。比如说,考虑 expurgate 函数。为了删除当前元素,程序需要访问iterator。而 for-each 循环隐藏了iterator,所以你不能调用 remove 函数。因此,对于过滤(filtering)操作,for-each 循环无能为力。类似地,如果你想在遍历一个list或数组的时候替换元素,它也无能为力。最后,对于必须平行地迭代多个集合的循环,它也无能为力。这些缺点,设计者已熟知,他们已经经过深思熟虑,决定使用一个在大多数情况下可用的整洁而简单的句式。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值