源码剖析Iterator接口遍历和直接for-get组合遍历的区别
来源:互联网 发布:专业软件开发学院 编辑:程序博客网 时间:2024/04/30 10:35
经常使用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 = ArrayList.this.elementData; if (i >= elementData.length)throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i];}
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
0 0
- 源码剖析Iterator接口遍历和直接for-get组合遍历的区别
- for(){}与iterator()遍历循环的区别
- Iterator,for,forEach的遍历和效率
- 数组遍历——iterator接口和for方法
- 一个完整的遍历速度测试--遍历list元素,用iterator() ,hasNext()与for的区别
- 遍历数组 iterator方法和for方法
- 关于 for循环和Iterator遍历
- for和Iterator遍历速度比较
- 遍历数组 iterator方法和for方法
- 遍历数组 iterator方法和for方法
- 遍历数组 iterator方法和for方法
- 测试for,foreach和Iterator遍历效率
- 遍历数组 iterator方法和for方法
- ES6 -- 遍历器Iterator和for...of
- 遍历数组 iterator方法和for方法
- 遍历数组 iterator方法和for方法
- 集合的遍历:Iterator接口、foreach
- 关于java list集合的for遍历和Iterator遍历的随想
- 动态规划3:合唱队形
- 进程与线程及其区别
- 图片转base64串及反转回图片
- 数组指针和指针数组的区别
- xml的一个内部透明,带边框的背景,可用于按钮之类
- 源码剖析Iterator接口遍历和直接for-get组合遍历的区别
- Linux下SCP命令不输入密码(免密码)备份
- java中字符窜与16进制,byte之间的转换
- Combinations
- ajax解析返回数据
- MongoDB应用实践思考
- makefile 终极模板文件。此文在手,编译我有!
- 『IOS』ios 获取屏幕的属性和宽度
- Struts2嵌入式部署FineReport报表开发