ArrayList简介
-
ArrayList是一个动态的数组,它继承了AbstractList类,实现了List、RandomAccess,、Cloneable、 java.io.Serializable接口的集合类。
-
而LinkedList是一个动态的集合链表,它继承了AbstractSequentialList类,实现了List、Deque、Cloneable、 java.io.Serializable接口的集合类。可以看到,LinkedList并没有去实现RandomAccess这个接口,我们不妨看看RandomAccess接口类是什么
可以看到,RandomAccess接口仅仅只是一个定义,并没有什么实际意义,通过API上的注释得知,它仅仅是一种标识,标志着实现该类的可以进行随机访问,也就是说ArrayList是支持数组的特性的------随机访问。而LinkedList底层是链表,不支持随机访问。
ArrayList遍历的几种方式
-
前期工作准备
Person类
package com.entity; public class Person { private Integer id; private String name; private String sex; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Person(Integer id, String name, String sex) { this.id = id; this.name = name; this.sex = sex; } public Person() { } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", sex='" + sex + '\'' + '}'; } }
测试类
package com.main; import com.entity.Person; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; public class ListTraverse { public static void main(String[] args) { List<Person> list = new ArrayList<Person>(); list.add(new Person(1,"braveOne","男")); list.add(new Person(2,"braveTwo","男")); } }
-
使用常见的for循环随机访问,通过索引来进行遍历
for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }
-
使用增强的for循环进行遍历
for (Person personList:list){ System.out.println(personList); }
-
使用迭代器Iterator进行遍历
Iterator<Person> iterator= list.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); }
-
forEach+Lambda表达式进行遍历
list.forEach(person -> { System.out.println(person); });
可以发现一共有4中方式来对ArrayList进行遍历,那这四种到低那种方式遍历的效率要高呢?
ArrayList四中遍历方式的效率
测试代码
package com.main;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* \* Created with IntelliJ IDEA.
* \* User: fight bravely
* \* Date: 2020/5/4
* \* Time: 17:48
* \* To change this template use File | Settings | File Templates.
* \* Description:
* \
*
* @author 雄
*/
public class ArrayListEfficiency {
public static void main(String[] args) {
List<Integer> list60 = addArrayListSize(60);
List<Integer> list600 = addArrayListSize(600);
List<Integer> list6000 = addArrayListSize(6000);
List<Integer> list60000 = addArrayListSize(60000);
List<Integer> list600000 = addArrayListSize(600000);
List<Integer> list6000000 = addArrayListSize(6000000);
List<Integer> list60000000 = addArrayListSize(60000000);
selectSize(list60);
selectSize(list600);
selectSize(list6000);
selectSize(list60000);
selectSize(list600000);
selectSize(list6000000);
selectSize(list60000000);
}
/**
* 输出结果
*
* @param list
*/
public static void selectSize(List<Integer> list) {
System.out.println("==============" + list.size() + "次数==============");
System.out.println("时间花费最少的是: " + selectTraverse(list));
}
/**
* 比较时间差
*
* @param list
* @return 返回时间差最小的
*/
public static String selectTraverse(List<Integer> list) {
Long beforeTime1, beforeTime2, beforeTime3, beforeTime4, afterTime1, afterTime2, afterTime3, afterTime4;
Long time1 = 0l;
Long time2 = 0l;
Long time3 = 0l;
Long time4 = 0l;
int j = 0;
String result;
Long minTime = 10000000000000000l;
beforeTime1 = System.nanoTime();
forTraverse(list);
afterTime1 = System.nanoTime();
time1 = afterTime1 - beforeTime1;
System.out.println("forTraverse:" + time1 / 1000 + "微秒");
beforeTime2 = System.nanoTime();
enhanceForTraverse(list);
afterTime2 = System.nanoTime();
time2 = afterTime2 - beforeTime2;
System.out.println("enhanceForTraverse:" + time2 / 1000 + "微秒");
beforeTime3 = System.nanoTime();
iteratorTraverse(list);
afterTime3 = System.nanoTime();
time3 = afterTime3 - beforeTime3;
System.out.println("iteratorTraverse:" + time3 / 1000 + "微秒");
beforeTime4 = System.nanoTime();
forEachAddLambdaTraverse(list);
afterTime4 = System.nanoTime();
time4 = afterTime4 - beforeTime4;
System.out.println("forEachAddLambdaTraverse:" + time4 / 1000 + "微秒");
Long[] minTimeArray = {time1, time2, time3, time4};
for (int i = 0; i < minTimeArray.length; i++) {
if (minTimeArray[i] < minTime) {
minTime = minTimeArray[i];
j = i;
}
}
if (j == 0) {
result = "for循环遍历:" + minTime / 1000 + "微秒";
} else if (j == 1) {
result = "增强for循环遍历:" + minTime / 1000 + "微秒";
} else if (j == 2) {
result = "Iterator循环遍历:" + minTime / 1000 + "微秒";
} else {
result = "forEach循环遍历:" + minTime / 1000 + "微秒";
}
return result;
}
/**
* 创建长度为size大小的ArrayList
*
* @param size
* @return
*/
public static List addArrayListSize(int size) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < size; i++) {
list.add(i);
}
return list;
}
/**
* 使用for循环遍历ArrayList
* @param list
*/
public static void forTraverse(List<Integer> list) {
for (int i = 0; i < list.size(); i++) {
list.get(i).hashCode();
}
}
/**
* 增强的for循环遍历ArrayList
* @param list
*/
public static void enhanceForTraverse(List<Integer> list) {
for (Integer integer : list) {
integer.hashCode();
}
}
/**
* 使用Iterator迭代器对ArrayList进行遍历
* @param list
*/
public static void iteratorTraverse(List<Integer> list) {
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
iterator.next().hashCode();
}
}
/**
* 使用forEach进行遍历
* @param list
*/
public static void forEachAddLambdaTraverse(List<Integer> list) {
list.forEach(p -> {
p.hashCode();
});
}
}
结果
==============60次数==============
forTraverse:37微秒
enhanceForTraverse:114微秒
iteratorTraverse:31微秒
forEachAddLambdaTraverse:53783微秒
时间花费最少的是: Iterator循环遍历:31微秒
==============600次数==============
forTraverse:169微秒
enhanceForTraverse:183微秒
iteratorTraverse:134微秒
forEachAddLambdaTraverse:128微秒
时间花费最少的是: forEach循环遍历:128微秒
==============6000次数==============
forTraverse:820微秒
enhanceForTraverse:693微秒
iteratorTraverse:629微秒
forEachAddLambdaTraverse:339微秒
时间花费最少的是: forEach循环遍历:339微秒
==============60000次数==============
forTraverse:4765微秒
enhanceForTraverse:4958微秒
iteratorTraverse:4187微秒
forEachAddLambdaTraverse:2224微秒
时间花费最少的是: forEach循环遍历:2224微秒
==============600000次数==============
forTraverse:4837微秒
enhanceForTraverse:7278微秒
iteratorTraverse:7538微秒
forEachAddLambdaTraverse:6408微秒
时间花费最少的是: for循环遍历:4837微秒
==============6000000次数==============
forTraverse:13340微秒
enhanceForTraverse:15073微秒
iteratorTraverse:11847微秒
forEachAddLambdaTraverse:11261微秒
时间花费最少的是: forEach循环遍历:11261微秒
==============60000000次数==============
forTraverse:129913微秒
enhanceForTraverse:105620微秒
iteratorTraverse:101002微秒
forEachAddLambdaTraverse:103978微秒
时间花费最少的是: Iterator循环遍历:101002微秒
可以发现,在遍历不同次数的情况下,遍历的效率高低并不唯一,但从整体上来看,forEach遍历的效率确实是要高于其他。