`
gcq04552015
  • 浏览: 462110 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

遍历ArrayList,Iterator和for循环哪个更快

 
阅读更多
Iterator 主要性能开销在next方法体,其一:对记录集进行检测,如果在迭代的过程中,记录集有被修改,会抛出异常;其二:next方法体内有try...catch方法体,这也会影响性能,JVM不能对try...catch块内的代码进行优化。
而for因为不管数据被中途修改,也不进行异常处理,所以当然快啦



详细:

ArrayList的iterator是在AbstractList里面的
它的next方法如下:

Java code
    public E next() {
            checkForComodification();
        try {
        E next = get(cursor);
        lastRet = cursor++;
        return next;
        } catch (IndexOutOfBoundsException e) {
        checkForComodification();
        throw new NoSuchElementException();
        }
    }


而其中的get为:
Java code
    public E get(int index) {
        rangeCheck(index);
        checkForComodification();
        return l.get(index+offset);
    }


看到这个l.get(index+offset)了没?这个l就是AbstractList本身
所以,最终调用的是ArrayList的get:
Java code
    public E get(int index) {
    RangeCheck(index);

    return (E) elementData[index];
    }


总结:对ArrayList而言,for里面的get比较单纯,而iterator的next多了checkForComodification,rangeCheck等,所以变慢了。




引用 5 楼 quqiujie 的回复:
把arrayList改为LinkedList,就知道结果了



LinkedList又是另外一个话题了,不过LZ的程序千万别不动脑筋的把ArrayList变成LinkedList呀。
LZ的程序的for循环,如果用LinkedList的话,慢死你没商量!
理由很简单LinkedList的get(int index)是调用AbstractSequentialList的public E get(int index):
Java code
    public E get(int index) {
        try {
            return listIterator(index).next();
        } catch (NoSuchElementException exc) {
            throw new IndexOutOfBoundsException("Index: "+index);
        }
    }


而listIterator(index)的最终是要调LinkedList的ListItr(int index):
Java code
    ListItr(int index) {
        if (index < 0 || index > size)
        throw new IndexOutOfBoundsException("Index: "+index+
                            ", Size: "+size);
        if (index < (size >> 1)) {
        next = header.next;
        for (nextIndex=0; nextIndex<index; nextIndex++)
            next = next.next;
        } else {
        next = header;
        for (nextIndex=size; nextIndex>index; nextIndex--)
            next = next.previous;
        }
    }


现在,知道有多慢了吧?一个for循环,从0知道到index,也就是说LZ的程序如果用LinkedList做for循环调get(int index)方法的话,算法复杂度为O(n*n)!

然而,LinkedList的Iterator却是个好东西。它的next为:
Java code
    public E next() {
        checkForComodification();
        if (nextIndex == size)
        throw new NoSuchElementException();

        lastReturned = next;
        next = next.next;
        nextIndex++;
        return lastReturned.element;
    }




简单吧?就一个next = next.next,全搞定!链表就是这个好,顺序遍历的时候很快,其实我觉得要比上面那个ArrayList的get(return elementData[index])要快。C里面也许数组挺快,但是Java里面,这个elementData是个Object数组,要求offset应该不是就一个乘法加一个加法那么简单吧?就算是一个乘法加一个加法,链表LinkedList就一个next的赋值(next是Entry)应该更快。



Iterator为什么产生?

ArrayList 和 LinkedList 是两个区别很大的集合, 没必要一起比嘛

Iterator 是集合提供的一个通用接口, 用来遍历集合元素的。在Collection下的集合都可以使用这个接口来遍历

提醒一下:用Iterator 迭代, 不是一样用了循环的嘛。
分享到:
评论

相关推荐

    ArrayList类操作程序实例

    六、遍历ArrayList 1. for-each循环:`for (E e : list) { ... }` 2. Iterator迭代器:`Iterator&lt;E&gt; iterator = list.iterator(); while (iterator.hasNext()) { E e = iterator.next(); ... }` 七、ArrayList的...

    ArrayList上机练习1

    - 直接使用`ArrayList`遍历:通过索引访问元素通常比`Iterator`更快,因为索引访问直接定位到内存位置。但是,当在遍历过程中需要删除元素时,`Iterator`提供了更好的安全性和性能。 总结来说,这个练习涵盖了`...

    Java 实例 - 集合遍历源代码-详细教程.zip

    遍历ArrayList通常使用for-each循环,这是一种简洁且高效的迭代方式: ```java ArrayList&lt;String&gt; list = new ArrayList(); list.add("A"); list.add("B"); list.add("C"); for (String item : list) { System....

    Arraylist初始应用

    可以使用迭代器或者增强型for循环遍历ArrayList: ```java // 使用迭代器 Iterator&lt;String&gt; iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } // 使用增强型for...

    Java遍历集合方法分析(实现原理、算法性能、适用场合)

    - 对于性能敏感的场景,应优先考虑ArrayList配合for循环或Iterator,避免使用LinkedList的for循环遍历。 - 当只需要读取元素且希望代码简洁时,可以使用foreach循环。 了解这些遍历方式的原理和性能特点,可以帮助...

    Iterator迭代器讲解

    例如,在`ArrayList`中,使用传统的`for`循环通常比使用`Iterator`更快,而`foreach`循环则介于两者之间。然而,在`LinkedList`等其他类型的集合中,`Iterator`的性能表现可能会优于传统的循环结构。 综上所述,`...

    Java系列ArrayList

    可以通过迭代器(Iterator)或增强for循环遍历ArrayList中的所有元素。 ```java // 使用迭代器 Iterator&lt;String&gt; iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next())...

    java ArrayList的使用与分析

    - **遍历元素**:可以使用 `for-each` 循环或迭代器进行遍历。 - **修改元素**:`list.set(index, newValue);` 3. **ArrayList 的重要方法和属性** - **构造器**: - 默认构造器:`ArrayList()`,初始容量为16...

    我的ArrayList实现

    前者通过改变数组元素的顺序来实现,后者则需要遍历ArrayList以找到目标元素,所以时间复杂度为O(n)。此外,ArrayList还提供了removeAll、retainAll等方法,用于批量删除或保留符合条件的元素。 在并发环境下,...

    Java list三种遍历方法性能比较

    在Java编程中,遍历List接口实现类(如ArrayList)有三种常见的方法:增强型for循环、普通for循环以及使用Iterator。本篇文章将详细探讨这三种遍历方式,并基于给出的测试代码分析它们的性能差异。 1. **增强型for...

    Iterator与fast-fail机制.pdf

    以ArrayList为例,对比普通的for循环和使用迭代器的区别: 1. 普通for循环: 这种方式需要显式地知道ArrayList的大小(通过size()方法),并通过索引(i)获取元素(通过get()方法)。这种方式与ArrayList的实现...

    java代码-使用集合ArrayList对字符串进行存储和管理。

    遍历ArrayList通常使用增强for循环或迭代器: ```java // 增强for循环 for (String str : stringList) { System.out.println(str); } // 迭代器 Iterator&lt;String&gt; iterator = stringList.iterator(); while ...

    Java基础增强

    - 示例代码中展示了如何使用ArrayList、HashMap、Iterator、Set等集合类,并通过增强型for循环和迭代器进行遍历操作。 - LinkedHashMap的使用可以保持插入顺序。 - 对于Map的遍历,可以使用entrySet()方法,其...

    实验05 集合类与泛型 实验报告.pdf

    9. **增强型for循环(foreach)**:实验中使用了增强型for循环遍历ArrayList,这种语法简化了遍历集合的过程,使得代码更简洁。 10. **继承与抽象类**:Mobile和Mp3Player是Product的子类,体现了面向对象的继承...

    java代码-使用集合ArrayList对字符串进行存储和管理,运行效果图:

    可以通过迭代器或者增强for循环遍历ArrayList中的元素: ```java // 使用迭代器 Iterator&lt;String&gt; iterator = stringList.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } // ...

    11.集合框架001-Collection接口1-3

    2. 遍历ArrayList的两种方式:for循环和foreach(增强型for循环)。 3. ArrayList的性能优化,如适当预估容量以减少扩容操作,以及在并发环境下考虑使用线程安全的List实现,如CopyOnWriteArrayList。 通过学习这个...

    java-array-list-foreach

    在处理ArrayList时,`foreach`循环(也称为增强for循环)是常用的迭代方式,它提供了一种简洁、易读的方式来遍历ArrayList中的所有元素。本文将深入探讨`foreach`循环在Java中使用ArrayList的应用及其背后的机制。 ...

    Collection类(集合类

    除了使用迭代器和增强for循环遍历外,还可以使用传统的for循环来遍历集合。不过这种方式需要注意索引越界问题,适用于知道集合大小的情况。 ```java public class DemoForLoop { public static void main(String[]...

    Java中List集合的遍历实例详解

    `foreach`循环和`for`循环的性能差异可能并不明显,但它们都比迭代器遍历更快。然而,性能优化通常需要结合具体场景和需求来考虑,单纯追求速度并不总是最佳策略。 总之,理解并熟练掌握Java中List集合的这三种遍历...

Global site tag (gtag.js) - Google Analytics