首页 > 代码库 > 源码剖析Iterator接口遍历和直接for-get组合遍历的区别
源码剖析Iterator接口遍历和直接for-get组合遍历的区别
经常使用ArrayList遍历,尝试总结一下for配合get()的遍历和Iterator配合next()遍历的区别,进入Java的JDK源码中进行深度剖析一下
这里参考一下http://bbs.csdn.net/topics/250025827论坛的测试程序:
import java.util.Iterator; import java.util.List; import java.util.ArrayList; import java.util.LinkedList; /** * IteratorTest * * @author SageZk */ public class IteratorTest { public static long testForloops(List<String> list) { long start = 0L; long end = 0L; start = System.nanoTime(); for (int i = list.size() - 1; i >= 0; --i) { list.get(i); } end = System.nanoTime(); return end - start; } public static long testIterator(List<String> list) { long start = 0L, end = 0L; start = System.nanoTime(); Iterator<String> it = list.iterator(); while (it.hasNext()) { it.next(); } end = System.nanoTime(); return end - start; } public static void main(String[] args) { // 测试列表长度 final int LEN = 10000; // 初始化测试用数据 List<String> arraylist = new ArrayList<String>(); List<String> linkedlist = new LinkedList<String>(); for (int i = 0; i < LEN; ++i) { String s = Integer.toString(i, 2); arraylist.add(s); linkedlist.add(s); } // 打印测试结果 final String FORMAT = "%1$-16s%2$-16s%3$16d\n"; System.out.println("List\t\tType\t\tTime(nanoseconds)"); System.out.println("-------------------------------------------------"); System.out.printf(FORMAT, "ArrayList", "for", testForloops(arraylist)); System.out.printf(FORMAT, "ArrayList", "Iterator", testIterator(arraylist)); System.out .printf(FORMAT, "LinkedList", "for", testForloops(linkedlist)); System.out.printf(FORMAT, "LinkedList", "Iterator", testIterator(linkedlist)); } }
运行程序:
ListTypeTime(nanoseconds)
-------------------------------------------------
ArrayList for 607064
ArrayList Iterator 809922
LinkedList for 154326455
LinkedList Iterator 958140
可以看到使用LinkedList链表式的列表遍历的话差距就很明显。
使用ArrayList列表的话,使用for比较快一些。
根据这里的区别,我跟踪了一下源码。
ArrayList的Iterator和for-get两种遍历
next
public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = http://www.mamicode.com/ArrayList.this.elementData;>get
private transient Object[] elementData; public E get(int index) { rangeCheck(index); return elementData(index); } E elementData(int index) { return (E) elementData[index]; }
可以看出两种方法使用的都是从Object[]数组中直接返回return (E) elementData[index]的形式读取节点,所以就区别而言,是for遍历的get的读取速度稍微快一点但是不会很明显,因为next()还需要进行一次指向赋值操作和基本类型的赋值。LinkedList的Iterator和for-get两种遍历
next
public E next() { checkForComodification(); if (!hasNext()) throw new NoSuchElementException(); lastReturned = next; next = next.next; nextIndex++; return lastReturned.item; } private Node<E> next; private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }get
public E get(int index) { checkElementIndex(index); return node(index).item; }
可以看出LinkedList的next是直接链式节点一个一个读取,这里的链式节点的next读取速度就可以和for循环的get读取速度拉开一个比较乐观的明显的距离了。总结一下
短评一下,如果是链式列表的话使用next(),如果只是一般的ArrayList进行遍历,使用for和get组合就可以了。for和get的配合,代码简单符合一般程序员的习惯,而且效率高,所以以后碰到ArrayList的遍历就不要在纠结下去了。本文来自CSDN博客,转载请联系作者注明出处http://blog.csdn.net/dreamintheworld
源码剖析Iterator接口遍历和直接for-get组合遍历的区别
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。