2015062906 - EffactiveJava笔记 - 第46条 foreach优先传统for循环(2)

    对多个集合嵌套迭代,for-each比for优势更明显.

    enum Suit { CLUB,DIAMOND,HEART,SPADE }

    enum Rank { ACE, DEUCE, THREE, FORE, FIVE, SIX,SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING}

 

    class Card {

       publicSuit suit;

       publicRank rank;

       publicCard(Suit suit, Rank rank) {

              this.suit= suit;

              this.rank= rank;

       }

          public static void main(String[] args) {

              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(newCard(i.next(), j.next()));

                     }

              }

              //Exceptionin thread "main" java.util.NoSuchElementException

          }

    }

    看不出问题很正常的,因为很多专家级程序员依旧看不出这样的错误.问题在于,在迭代器对外部的集合suits调用太多次next方法.它应该在外部循环中进行,以便每种花色只调用1次,但是却从内部循环中调用多次,当然用完所有花色后,出现java.util.NoSuchElementException.

 

    比出现异常更糟糕的情况,外部集合大小是内部集合大小的若干倍,可能因为它们是相同的集合,循环就会正常终止,但不会完成你想要的工作.下面代码考虑不周,打印一对骰子的所有可能滚法.

    enum Face {ONE, TWO, THREE, FORE, 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.err.println(i.next()+ "   "+ j.next());

        }

    }

    与预期的目标36种不符合,只是打印6种情况.结果如下:

    ONE   ONE

    TWO   TWO

    THREE   THREE

    FORE   FORE

    FIVE   FIVE

    SIX   SIX

   //具体为何,如果不知道,请断点调试.一目了然.

 

    如何解决上面的两个问题呢?必须在外部循环的作用域中添加变量保存外部元素.

    for (Iterator<Suit> i =suits.iterator(); i.hasNext();) {

         Suit suit = (i.next();

         for(Iterator<Rank> j = ranks.iterator(); j.hasNext();) {

               deck.add(newCard(suit, j.next()));

         }

    }

 

    如果使用嵌套for-each循环,此问题彻底消失,产生的代码如你所愿那样简洁.

    for (Suit s: suits)

       for(Rankrank:ranks)

              deck.add(newCard(suit,rank))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值