foreach与Iterator的一些事

1:foreach与Iterator

最近在阅读Java编程思想第11章看到了Foreach与迭代器,文中说到“foreach语法主要用于数组,但是它也可以应用于任何Collection对象,任何实现了Iterator接口的类,都可以将它用于foreach语句中”,其实Iterator就是告诉foreach如何在序列中移动元素,到底是每次向前移动一个元素还是向后移动一个元素具体看你如何实现的Iterator接口了,下面就是Iterator接口的方法,总共也就是三个,hasNext() next() 和 remove(),刚才说到的具体如何在序列中移动元素对应到就是如何实现的next()方法.

public interface Iterator<E> {

    boolean hasNext();

    E next();

    void remove();
}

2:foreach的本质

隐约记得foreach实则还是调用的Iterator,本着学习的目的想去查看下foreach的源码却发现并没有,也看了不少类似的文章确实通过反编译可以进行证实,这里附上反编译前后的方法对比

反编译前

    public static void testForEach(List persons) {  
        Object curPerson;  
        for(Object person : persons){
            curPerson = person;  
        }           
    } 

反编译后

    public static void testForEach(List persons) {  
        for (Iterator iterator = persons.iterator(); iterator.hasNext();) {  
            Object person = iterator.next();  
            Object obj = person;  
        }  
    }  

从反编译后的结果可以明显看出foreach实则还是通过迭代器实现的,其实在编译期就进行这步替换,即将foreach替换为Iterator。

3:效率

自己也是亲自对两种遍历方式的效率进行了测试,主要还是使用了常用的ArrayList进行的测试。
测试的结果如下

量值 foreach遍历耗时(ms) Iterator遍历耗时(ms)
10000 5998 5377
100000 18743 16054
1000000 29426 22207

从测试的结果来看foreach的遍历性能略低于Iterator

附:测试的源代码,其中的Person为一简单的实体类,仅包含String name和int age两个属性

        /*
         * System.nanoTime()获取的时间单位为纳秒
         */
        List<Person> persons = new ArrayList<Person>();
        for(int i=0;i<1000000;i++){
            persons.add(new Person("Muyi"+i,i));
        }
        System.out.println(persons.size());
        Person curPerson = null;
        long beginTime = System.nanoTime();
        for(Person person:persons){
            curPerson = person;
        }
        long currentTime = System.nanoTime();
        System.out.println("Foreach UseTime:"+(currentTime-beginTime)/1000);
        Iterator<Person> iterator = persons.iterator();
        beginTime = System.nanoTime();
        while(iterator.hasNext()){
            curPerson = iterator.next();
        }
        currentTime = System.nanoTime();
        System.out.println("Iterator UseTime:"+(currentTime-beginTime)/1000);

猜你喜欢

转载自blog.csdn.net/Noonebirdyou/article/details/78397976
今日推荐