RandomAccess接口:这是一个标记接口,如果List子类实现了RandomAccess接口,那就表示它能够快速随机访问存储的元素。在对列表进行随机或顺序访问的时候,访问算法能够选择性能最佳方式。
/**
* 初始化 list,添加n个元素
*
* @param list
* @return
*/
public static <T> List initList(List list, int n) {
for (int i = 0; i < n; i++)
list.add(i);
return list;
}
/**
* 遍历 list,判断是否实现 RandomAccess 接口来使用不同的遍历方法
*
* @param list
*/
public static void accessList(List list) {
long startTime = System.currentTimeMillis();
if (list instanceof RandomAccess) {
System.out.println("实现了 RandomAccess 接口...");
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
} else {
System.out.println("没实现 RandomAccess 接口...");
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
iterator.next();
}
}
long endTime = System.currentTimeMillis();
System.out.println("遍历时间:" + (endTime - startTime));
}
/**
* loop 遍历 list
*/
public static void accessListByLoop(List list) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
long endTime = System.currentTimeMillis();
System.out.println("loop遍历时间:" + (endTime - startTime));
}
/**
* forEach 遍历 list
*/
public static void accessListByForEach(List list) {
long startTime = System.currentTimeMillis();
for (Object obj : list) {
}
long endTime = System.currentTimeMillis();
System.out.println("forEach遍历时间:" + (endTime - startTime));
}
/**
* 迭代器遍历
*/
public static void accessListByIterator(List list) {
long startTime = System.currentTimeMillis();
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
iterator.next();
}
long endTime = System.currentTimeMillis();
System.out.println("Iterator遍历时间:" + (endTime - startTime));
}
@Test
public void testRandomAccess(){
ArrayList<Integer> aList = (ArrayList<Integer>) initList(new ArrayList<>(), 50000);
LinkedList<Integer> lList = (LinkedList<Integer>) initList(new LinkedList<>(), 50000);
accessList(aList);
accessList(lList);
System.out.println("ArrayList");
accessListByLoop(aList);
accessListByForEach(aList);
accessListByIterator(aList);
System.out.println("LinkedList");
accessListByLoop(lList);
accessListByForEach(lList);
accessListByIterator(lList);
}
执行结果
- 使用ArrayList遍历时将list大小改为2000000执行结果如下:
实现了 RandomAccess 接口...
遍历时间:13
没实现 RandomAccess 接口...
遍历时间:38
ArrayList
loop遍历时间:13
forEach遍历时间:19
Iterator遍历时间:20
- 使用LinkedList遍历时将list大小改为50000执行结果如下:
实现了 RandomAccess 接口...
遍历时间:11
没实现 RandomAccess 接口...
遍历时间:17
LinkedList
loop遍历时间:6134
forEach遍历时间:16
Iterator遍历时间:16
结论:明显可以看出在遍历ArrayList时for循环的效率最高,而在遍历LinkList时for循环的效率要远远最低;原因就是ArrayList实现了RandomAccess接口,拥有快速随机访问存储的元素的功能,而LinkList则没有此功能。