标签:
ArrayList支持三种遍历方式。
由于ArrayList实现了RandomAccess接口,它支持通过索引值去随机访问元素。
代码如下:
// 基本的for
for (int i = 0; i < size; i++)
{
value = list.get(i);
}
for (Integer integer : list)
{
value = integer;
}
迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的。只要拿到这个对象,使用迭代器就可以遍历这个对象的内部。
代码如下:
for (Iterator<Integer> iterator = list.iterator(); iterator.hasNext();)
{
value = iterator.next();
}
要想知道上面几种遍历方式的效率如何,最简单的办法,就是我们自己编写代码来测试它。
测试代码如下:
/**
* 测试ArrayList中几种循环的效率
*
* @author Administrator
* @version 1.0
*/
public class TestArrayListLoop
{
public static void main(String[] args)
{
// 准备数据阶段
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 100000; i++)
{
list.add(i);
}
// 测试阶段
int runCounts = 1000; // 执行次s数
int listSize = list.size();
int value;
// For循环的测试
long startTime1 = System.currentTimeMillis();
for (int i = 0; i < runCounts; i++)
{
loopOfFor(list);
}
long endTime1 = System.currentTimeMillis();
// Foreach循环的测试
long startTime2 = System.currentTimeMillis();
for (int i = 0; i < runCounts; i++)
{
loopOfForeach(list);
}
long endTime2 = System.currentTimeMillis();
// Iterator迭代器的测试
long startTime3 = System.currentTimeMillis();
for (int i = 0; i < runCounts; i++)
{
loopOfIterator(list);
}
long endTime3 = System.currentTimeMillis();
System.out.println("loopOfFor: " + (endTime1-startTime1)+ "ms");
System.out.println("loopOfForeach: "+ (endTime2-startTime2)+ "ms");
System.out.println("loopOfIterator: "+ (endTime3-startTime3)+ "ms");
}
/**
* 由于ArrayList实现了RandomAccess接口,它支持通过索引值去随机访问元素。
* @param list
*/
public static void loopOfFor(List<Integer> list)
{
int value;
int size = list.size();
// 基本的for
for (int i = 0; i < size; i++)
{
value = list.get(i);
}
}
/**
* 使用forecah方法遍历数组
* @param list
*/
public static void loopOfForeach(List<Integer> list)
{
int value;
// foreach
for (Integer integer : list)
{
value = integer;
}
}
/**
* 通过迭代器方式遍历数组
* @param list
*/
public static void loopOfIterator(List<Integer> list)
{
int value;
// iterator
for (Iterator<Integer> iterator = list.iterator(); iterator.hasNext();)
{
value = iterator.next();
}
}
}
loopOfFor: 72ms
loopOfForeach: 89ms
loopOfIterator: 91ms
loopOfFor: 70ms
loopOfForeach: 90ms
loopOfIterator: 87ms
loopOfFor: 668ms
loopOfForeach: 760ms
loopOfIterator: 679ms
loopOfFor: 672ms
loopOfForeach: 751ms
loopOfIterator: 678ms
As a rule of thumb, a List implementation should implement this interface if, for typical instances of the class, this loop:
for (int i=0, n=list.size(); i < n; i++) list.get(i);runs faster than this loop:
for (Iterator i=list.iterator(); i.hasNext(); ) i.next();
public Iterator<E> iterator() {
return new Itr();
}
public Iterator<E> iterator()
{
return new Itr();
}
// An optimized version of AbstractList.Itr
private class Itr implements Iterator<E>
{
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext()
{
return cursor != size;
}
@SuppressWarnings("unchecked")
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];
}
public void remove()
{
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try
{
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex)
{
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer)
{
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size)
{
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
{
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount)
{
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification()
{
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
LinkedList中的结论正确吗?我们做个实验,测试一下就会水落石出。
代码如下:
public class TestLinkedListLoop
{
public static void main(String[] args)
{
// 准备数据阶段
List<Integer> list = new LinkedList<Integer>();
for (int i = 0; i < 10000; i++)
{
list.add(i);
}
// 测试阶段
int runCounts = 10; // 执行次s数
int listSize = list.size();
int value;
// For循环的测试
long startTime1 = System.currentTimeMillis();
for (int i = 0; i < runCounts; i++)
{
loopOfFor(list);
}
long endTime1 = System.currentTimeMillis();
// Foreach循环的测试
long startTime2 = System.currentTimeMillis();
for (int i = 0; i < runCounts; i++)
{
loopOfForeach(list);
}
long endTime2 = System.currentTimeMillis();
// Iterator迭代器的测试
long startTime3 = System.currentTimeMillis();
for (int i = 0; i < runCounts; i++)
{
loopOfIterator(list);
}
long endTime3 = System.currentTimeMillis();
System.out.println("loopOfFor: " + (endTime1-startTime1)+ "ms");
System.out.println("loopOfForeach: "+ (endTime2-startTime2)+ "ms");
System.out.println("loopOfIterator: "+ (endTime3-startTime3)+ "ms");
}
/**
* 由于ArrayList实现了RandomAccess接口,它支持通过索引值去随机访问元素。
* @param list
*/
public static void loopOfFor(List<Integer> list)
{
int value;
int size = list.size();
// 基本的for
for (int i = 0; i < size; i++)
{
value = list.get(i);
}
}
/**
* 使用forecah方法遍历数组
* @param list
*/
public static void loopOfForeach(List<Integer> list)
{
int value;
// foreach
for (Integer integer : list)
{
value = integer;
}
}
/**
* 通过迭代器方式遍历数组
* @param list
*/
public static void loopOfIterator(List<Integer> list)
{
int value;
// iterator
for (Iterator<Integer> iterator = list.iterator(); iterator.hasNext();)
{
value = iterator.next();
}
}
}
loopOfFor: 332ms
loopOfForeach: 5ms
loopOfIterator: 4ms
public void display(Iterator<object> it)当我们需要遍历不同的集合时,我们只需要传递集合的iterator(如arr.iterator())看懂了吧,这就是iterator的好处,他不包含任何有关他所遍历的序列的类型信息,能够将遍历序列的操作与序列底层的结构分离。迭代器统一了对容器的访问方式。这也是接口的解耦的最好体现。
{
while(it.hasNext())
{
system.out.print(it.next()+"");
}
}
for循环:一般用来处理比较简单的有序的,可预知大小的集合或数组
foreach:可用于遍历任何集合或数组,而且操作简单易懂,他唯一的不好就是需要了解集合内部类型
iterator:是最强大的,它可以随时修改或者删除集合内部的元素,并且是在不需要知道元素和集合的类型的情况下进行的(原因可参考第三点:多态差别),当你需要对不同的容器实现同样的遍历方式时,迭代器是最好的选择!
参考:
3、Java迭代器(转)(iterator详解以及和for循环的区别)
标签:
原文地址:http://www.cnblogs.com/aoguren/p/4771589.html