跟我学(Effective Java 2)第46条:for-each循环优先于传统的for循环
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了跟我学(Effective Java 2)第46条:for-each循环优先于传统的for循环,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2491字,纯文字阅读大概需要4分钟。
内容图文
第46条:for-each循环优先于传统的for循环
for-each循环通过完全隐藏迭代器或者索引变量,避免混乱和出错的可能,适用于集合和数组和任何实现Iterable接口的对象。
enum Suit { CLUB, DIAMOND, HEART, SPADE }
enum Rank { ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT,
NINE, TEN, JACK, QUEEN, KING }
...
Collection<Suit> suits = Arrays.asList(Suit.values());
Collection<Rank> ranks = Arrays.asList(Rank.values());
List<Card> deck = new ArrayList<Card>();
for (Iterator<Suit> i = suits.iterator(); i.hasNext(); )
for (Iterator<Rank> j = ranks.iterator(); j.hasNext(); )
deck.add(new Card(i.next(), j.next()));
如果你没有发现这个bug也不用难过,许多专家级的程序员也偶尔会犯这种错误。问题在于,在迭代器上对外层集合(suits)调用了太多次next的方法。它应该从外层循环被调用,以便每个suit调用一次,但是它却是在内层循环中被调用,变成了每个card调用一次。在你运行完suits,循环会抛出NoSuchElementException。
如果你很不幸,外层集合的长度是内层集合大小的几倍–可能因为它们是相同的集合–循环会正常中止,但结果却不是你想要的。例如,考虑下面有问题的代码,它企图打印所有可能的成对骰子数。
enum Face { ONE, TWO, THREE, FOUR, FIVE, SIX }
Collection<Face> faces = Arrays.asList(Face.values());
for(Iterator<Face> i = faces.iterator(); i.hasNext();)
for(Iterator<Face> j = faces.iterator(); j.hasNext();)
System.out.println(i.next() + " " + j.next());
期望打印预计的36中组合,结果却是6个重复的词。
修正方法:
for (Iterator<Suit> i = suits.iterator(); i.hasNext(); ) {
Suit suit = i.next();
for (Iterator<Rank> j = ranks.iterator(); j.hasNext(); )
deck.add(new Card(suit, j.next()));
}
使用嵌套for-each循环更简洁:
for (Suit suit : suits)
for (Rank rank : ranks)
deck.add(new Card(suit, rank));
or-each不仅可在集合和数组上迭代,而且还可在任何实现了Iterable接口的对象上迭代。接口Iterablel有一个简单的方法,随for-each一起加入平台,接口如下:
public interface Iterable<E> {
Iterator<E> iterator();
}
实现Iterable接口并不困难。如果所写的类型代表一组元素,即便不让他实现Collection接口也应该让它实现Iterable接口。这会让你的用户可以通过for-each循环在你的类型上迭代,你的用户会永远感谢你。
总之,使用嵌套for-each循环更简洁,代码优雅,性能略胜于普通for循环,因为它对数组索引的边界值只计算一次。
无法使用for-each循环的情况:
1.过滤 ,需要遍历集合并删除选定的元素,需要显式的迭代器,以便调用它的remove方法。
2.转换 ,需要遍历列表或者数组,并取代它部分或者全部元素值,需要列表迭代器或者数组索引,以便设定元素的值。
3.平行迭代 ,并行地遍历多个集合,需要显式地控制迭代器或者索引变量,以便所有迭代器和索引变量都可以得到同步前移(像上述第一个代码 块那样)。
内容总结
以上是互联网集市为您收集整理的跟我学(Effective Java 2)第46条:for-each循环优先于传统的for循环全部内容,希望文章能够帮你解决跟我学(Effective Java 2)第46条:for-each循环优先于传统的for循环所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。