传统for VS 增强for

传统for VS 增强for

Java 1.5版本发布之前,首选遍历集合和数组方法:

        //遍历集合
        List list = new ArrayList<Integer>();
        list.add(3);
        list.add(2);
        list.add(5);
        list.add(8);
        list.add(4);
        list.add(7);
        list.add(6);
        list.add(9);
        System.out.print("list output:   ");
        for(Iterator i = list.iterator(); i.hasNext();){
            System.out.print(i.next() + "  ");
        }

        //遍历数组
        int[] array = {3, 2, 5, 8, 4, 7, 6, 9};
        System.out.print("array output:   ");
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + "  ");
        }

而这种做法并不总是最佳的。因为迭代器和索引变量都会造成一些混乱,与此同时也代表了出错的可能。

迭代器和索引变量在每个循环中出现三次,其中两次很容易出错,一旦出错就无法保证编译器能够发现错误。


Sun 公司Java 开发团队将for-each 循环引入到Java 1.5版本。主要特点是完全隐藏迭代器或索引变量。

for-each 使用场景有三种:

    1> 遍历数组

    2> 遍历Collection 下的集合

    3> 遍历任何实现Iterable 接口的对象

for-each 无法使用的三种场景:

    1> 遍历集合时要删除选定元素

    2> 遍历列表或数组时,需要取代它部分或全部的元素值

    3> 并行遍历多个集合

for 循环与for-each 循环的关系语法糖

性能比较

    不会产生性能损失。相反,在实际开发过程中,for-each相较与传统for有时反而会稍有性能优势。因为它对于数组索引只计算一次 ( 虽然这项工作也可手工完成,但程序员不总会这样做 ) 。

对多个集合进行嵌套迭代时,for-each优势更加明显。我们就以纸牌游戏进行举例:

enum Suit {
    CLUB, DIAMOND, HEART, SPADE,

}

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

}

class Card{
    public Suit suit;
    Rank rank;

    public Card() {

    }

    public Card(Suit suit, Rank rank) {
        this.suit = suit;
        this.rank = rank;
    }

    public Suit getSuit() {
        return suit;
    }

    public Rank getRank() {
        return rank;
    }
}
public class Demo {

    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>();

        /*
        错误方法
        因为在内部循环中调用了太多次suits的next()方法,所以会抛出NoSuchElementException 异常
        因将对suits的next() 调用放在外部循环,以便每种花色调用一次
         */

//        for (Iterator<Suit> i = suits.iterator(); i.hasNext(); ) {
//            for (Iterator<Rank> j = ranks.iterator(); j.hasNext(); ) {
//                deck.add(new Card(i.next(), j.next()));
//            }
//        }

        //修改后的方法
//        for (Iterator<Suit> i = suits.iterator(); i.hasNext(); ) {
//            Suit s = i.next();
//            for (Iterator<Rank> j = ranks.iterator(); j.hasNext(); ) {
//                deck.add(new Card(s, j.next()));
//            }
//        }

        //此时for-each的优势就显现出来啦
        for (Suit s : suits) {
            for (Rank r : ranks) {
                deck.add(new Card(s, r));
            }
        }

        //输出deck集合
        for (Card d : deck) {
            System.out.println(d.getSuit() + "   " + d.getRank());
        }
        
    }
}

总之,for-each 循环在简洁性预防Bug 方面有着for 循环无法比拟的效果委屈...

参考文献:《Effective Java》

猜你喜欢

转载自blog.csdn.net/ib_yeang/article/details/79955597