java for-each的使用场景和使用方法

   使用for-each的可以是一个数组,或者是实现Iterable<T>这个接口的对象(Collection<E>继承了这个接口,所有集合类都可以使用for-each)

   既然for循环能遍历一个数组或者集合,那么为什么还会有一个for-each做遍历呢?下面(参考了jdk1.8api)举例说明:

for循环遍历每一个TimerTask类型的元素,然后调用其cancel方法。

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

  你能从上面的代码发现有什么问题吗?如上确实能实现遍历操作集合元素的功能,但是迭代器变量在每个循环中出现三次,for-each构造摆脱了这样的问题。

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

    冒号(:)读作“in”,上面的循环读作“对于c中的每个TimerTask t”。正如您所看到的,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()));
  问题是“外部”集合(套装)上被调用了太多次。它在外部和内部集合的内部循环中被调用,这是错误的。
为了解决这个问题,在外循环的范围内添加一个变量来保存这个套装:


// 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构造也适用于数组,它隐藏了索引变量而不是迭代器。以下方法返回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方法。该程序需要访问迭代器才能删除当前元素。for-each循环隐藏了迭代器,所以你不能调用remove。因此,for-each循环不能用于遍历时有删除操作。同样,它不适用于需要在遍历列表或数组时替换元素的循环。最后,它不能用于必须并行迭代多个集合的循环。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值