最近查看ArrayList 与 LinkedList 的效率问题,网上答复基本都是
ArrayList底层是用数组来保存对象的,这种方式将对象放在连续的位置中。
优点:可以通过数组下标快速的拿到值,查询时高效。
缺点:每一次添加和删除都需要将操作的元素后面的元素们全部移动,非常麻烦。
LinkedList则是将对象放在独立的空间中,而且在每一个空间中存放下一个链接的索引。
优点:增加和删除非常快速。
缺点:要定位元素的位置时,要从头一个一个寻找,耗费资源。
所以写了些代码进行验证,代码如下:
public class testList {
private final static int length = 3000000;
private final static int minLength = 8000;
public static void main(String[] args) {
List<String> array = array();
List<String> link = link();
//flag 1随机 2尾部 3前部
arrayIndex(array, 1);
linkIndex(link, 1);
arrayRemove(array, 1);
linkRemove(link, 1);
arrayIndex(array, 2);
linkIndex(link, 2);
arrayRemove(array, 2);
linkRemove(link, 2);
arrayIndex(array, 3);
linkIndex(link, 3);
arrayRemove(array, 3);
linkRemove(link, 3);
arrayQuery(array, 1);
linkQuery(link, 1);
arrayQuery(array, 2);
linkQuery(link, 2);
arrayQuery(array, 3);
linkQuery(link, 3);
}
public static List<String> array() {
long startTime = System.currentTimeMillis();
List<String> list = new ArrayList<String>();
for (int i = 0; i < length; i++) {
list.add("a");
}
long endTime = System.currentTimeMillis();
System.out.println("array 耗时:" + (endTime - startTime));
return list;
}
public static List<String> link() {
long startTime = System.currentTimeMillis();
List<String> list = new LinkedList<String>();
for (int i = 0; i < length; i++) {
list.add("a");
}
long endTime = System.currentTimeMillis();
System.out.println("link 耗时:" + (endTime - startTime));
return list;
}
public static List<String> arrayIndex(List<String> list, int flag) {
int len = length;
if (flag != 2) {
len = minLength;
}
long startTime = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
int size = 0;
if (flag == 1) {
size = (int) (Math.random() * length);
} else if (flag == 2) {
size = list.size() - 1;
}
list.add(size, "a");
}
long endTime = System.currentTimeMillis();
if (flag == 1) {
System.out.println("随机插入 arrayIndex 耗时:" + (endTime - startTime));
} else if (flag == 2) {
System.out.println("尾部插入 arrayIndex 耗时:" + (endTime - startTime));
} else {
System.out.println("前部插入 arrayIndex 耗时:" + (endTime - startTime));
}
return list;
}
public static List<String> linkIndex(List<String> list, int flag) {
int len = length;
if (flag != 2) {
len = minLength;
}
long startTime = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
int size = 0;
if (flag == 1) {
size = (int) (Math.random() * length);
} else if (flag == 2) {
size = list.size() - 1;
}
list.add(size, "a");
}
long endTime = System.currentTimeMillis();
if (flag == 1) {
System.out.println("随机插入 linkIndex 耗时:" + (endTime - startTime));
} else if (flag == 2) {
System.out.println("尾部插入 linkIndex 耗时:" + (endTime - startTime));
} else {
System.out.println("前部插入 linkIndex 耗时:" + (endTime - startTime));
}
return list;
}
public static List<String> arrayRemove(List<String> list, int flag) {
int len = length;
if (flag != 2) {
len = minLength;
}
long startTime = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
int size = 0;
if (flag == 1) {
size = (int) (Math.random() * length);
} else if (flag == 2) {
size = list.size() - 1;
}
list.remove(size);
}
long endTime = System.currentTimeMillis();
if (flag == 1) {
System.out.println("随机删除 arrayRemove 耗时:" + (endTime - startTime));
} else if (flag == 2) {
System.out.println("尾部删除 arrayRemove 耗时:" + (endTime - startTime));
} else {
System.out.println("前部删除 arrayRemove 耗时:" + (endTime - startTime));
}
return list;
}
public static List<String> linkRemove(List<String> list, int flag) {
int len = length;
if (flag != 2) {
len = minLength;
}
long startTime = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
int size = 0;
if (flag == 1) {
size = (int) (Math.random() * length);
} else if (flag == 2) {
size = list.size() - 1;
}
list.remove(size);
}
long endTime = System.currentTimeMillis();
if (flag == 1) {
System.out.println("随机删除 linkRemove 耗时:" + (endTime - startTime));
} else if (flag == 2) {
System.out.println("尾部删除 linkRemove 耗时:" + (endTime - startTime));
} else {
System.out.println("前部删除 linkRemove 耗时:" + (endTime - startTime));
}
return list;
}
public static void arrayQuery(List<String> list, int flag) {
int len = length;
if (flag != 2) {
len = minLength;
}
long startTime = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
int size = 0;
if (flag == 1) {
size = (int) (Math.random() * length);
} else if (flag == 2) {
size = list.size() - 1;
}
list.get(size);
}
long endTime = System.currentTimeMillis();
if (flag == 1) {
System.out.println("随机查询 arrayQuery 耗时:" + (endTime - startTime));
} else if (flag == 2) {
System.out.println("尾部查询 arrayQuery 耗时:" + (endTime - startTime));
} else {
System.out.println("前部查询 arrayQuery 耗时:" + (endTime - startTime));
}
}
public static void linkQuery(List<String> list, int flag) {
int len = length;
if (flag != 2) {
len = minLength;
}
long startTime = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
int size = 0;
if (flag == 1) {
size = (int) (Math.random() * length);
} else if (flag == 2) {
size = list.size() - 1;
}
list.get(size);
}
long endTime = System.currentTimeMillis();
if (flag == 1) {
System.out.println("随机查询 linkQuery 耗时:" + (endTime - startTime));
} else if (flag == 2) {
System.out.println("尾部查询 linkQuery 耗时:" + (endTime - startTime));
} else {
System.out.println("前部查询 linkQuery 耗时:" + (endTime - startTime));
}
}
}
结果如下:
array 耗时:45
link 耗时:48
随机插入 arrayIndex 耗时:7943
随机插入 linkIndex 耗时:18289
随机删除 arrayRemove 耗时:7656
随机删除 linkRemove 耗时:18342
尾部插入 arrayIndex 耗时:647
尾部插入 linkIndex 耗时:708
尾部删除 arrayRemove 耗时:12
尾部删除 linkRemove 耗时:30
前部插入 arrayIndex 耗时:14625
前部插入 linkIndex 耗时:4
前部删除 arrayRemove 耗时:14094
前部删除 linkRemove 耗时:1
随机查询 arrayQuery 耗时:2
随机查询 linkQuery 耗时:18845
尾部查询 arrayQuery 耗时:7
尾部查询 linkQuery 耗时:9
前部查询 arrayQuery 耗时:0
前部查询 linkQuery 耗时:0
结论:
尾部(插入 删除) 随机 (插入 删除) 的时候 array 比link要快
前部 (插入 删除) 的时候 link比array快
查询 array比link快 但是前部 或 尾部 查询的时候效率相差不大
ArrayList 与 LinkedList 适用场景:
当需要对数据进行对此访问的情况下选用ArrayList,当需要对数据进行多次(前部)增加删除修改时采用LinkedList