for-each循环优先于传统的for循环

来源:互联网 发布:内存涨价 知乎 编辑:程序博客网 时间:2024/05/16 00:47

对于遍历数组或者集合的元素来说,一般我们都会想到用传统的for循环,要么使用数组下标进行索引,要么使用集合的迭代器进行遍历,迭代器和索引变量在每个循环中出现三次,其中有两次是非常容易出现错误的,一旦出现错误,有可能编译器不能发现错误。

在java1.5中发行版本中引入的for-each循环,其中隐藏了迭代器或者索引变量,避免混乱和出错的可能。

看看下面的例子就很容出现错误:

//花色public enum Suit {    CLUB,DIAMOND,HEART,SPARE}//大小public enum Rank {    ACE,DEUCE,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN,JACK,QUEEN,KING}public class Card {    static Collection<Suit> suit=Arrays.asList(Suit.values());    static Collection<Rank> rank=Arrays.asList(Rank.values());    public static void main(String[] args) {        for(Iterator<Suit> i=suit.iterator();i.hasNext();){            for(Iterator<Rank> j=rank.iterator();j.hasNext();){                System.out.println(i.next()+"+"+j.next());            }        }    }}

结果:
CLUB+ACE
DIAMOND+DEUCE
HEART+THREE
SPARE+FOUR
Exception in thread “main” java.util.NoSuchElementException
at java.util.AbstractList$Itr.next(AbstractList.java:364)
at com.num46.Card.main(Card.java:15)

注意此程序的陷阱,此程序想打印出一副没有大小王的牌,用迭代器进行遍历。但是打印出来是错误的结果,是因为程序在里面进行了遍历,两个循环进行每一次遍历之后,内外层都会进行遍历。
当外层的循环比内层的循环的次数更小时,会抛出NoSuchElementException的异常

程序的改进:
方法一:在外层循环的作用域中,添加一个变量保存外层元素

public static void main(String[] args) {        for(Iterator<Suit> i=suit.iterator();i.hasNext();){            Suit suitValue=i.next();            for(Iterator<Rank> j=rank.iterator();j.hasNext();){                System.out.println(suitValue+"+"+j.next());            }        }    }

这样便能打印出正常的结果,但是这种方法还是会出现迭代器或者数组的索引变量,容易造成混乱。这时候就应该用到for-each循环

方法二:使用for-each循环

static void foreachMethod(){        for (Suit suit2 : suit) {            for (Rank rank2 : rank) {                System.out.println(suit2+"+"+rank2);            }        }    }

从上面的例子可以看出,使用for-each循环以后,程序清晰了很多,并且不容易出错。

再看看类似的陷阱

public enum Face {    ONE,TWO,THREE,FOUR,FIVE,SIX}public class Dot {    static Collection<Face> dot1=Arrays.asList(Face.values());    static Collection<Face> dot2=Arrays.asList(Face.values());    public static void main(String[] args) {        for (Iterator<Face> i=dot1.iterator(); i.hasNext(); ) {            for (Iterator<Face> j = dot2.iterator(); j.hasNext(); ) {                System.out.println(i.next()+" + "+j.next());            }        }    }}

上面的例子是同时投掷两个骰子,打印出所有的情况,但是打印的结果是6种结果,而不是36种结果

结果:
ONE + ONE
TWO + TWO
THREE + THREE
FOUR + FOUR
FIVE + FIVE
SIX + SIX

解决的方法是用上面的两种解决方法,但是用for-each循环比较好

for-each循环能遍历所有实现了Iterable接口的对象!!!!

总之,for-each循环在简洁性和预防Bug方面是传统for循环是做不到的,并且其对于for循环来说还没有性能损失,在某些情况下还可能比传统的for循环还稍微有些性能优势,故要尽量使用for-each循环。

0 0