面试题: arraylist与linkendlist的区别
一般大家都知道ArrayList和LinkedList的区别:
1、ArrayList的实现是基于数组,LinkedList的实现是基于双向链表。
2、对于随机访问,ArrayList优于LinkedList
3、对于插入和删除操作,LinkedList优于ArrayList
4、LinkedList比ArrayList更占内存,因为LinkedList的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。
一.在时间复杂度上的区别
假设我们有两个很大的列表,它们里面的元素已经排好序了,这两个列表分别是ArrayList类型和LinkedList类型的,现在我们对这两个列表来进行二分查找(binary search),比较它们的查找速度。
package com.example.demo.test1;
import java.util.*;
/**
* @program: test
* @description:
* @author: liulq
* @create: 2022-01-05 11:58
*/
public class Day3 {
static List array = new ArrayList();
static List linked = new LinkedList();
public static void main (String[]args){
for (int i = 0; i < 10000; i++) {
array.add(i);
linked.add(i);
}
System.out.println("ArrayList访问消耗的时间:" + getTime(array));
System.out.println("LinkedList访问消耗的时间:" + getTime(linked));
}
public static long getTime (List list){
long time = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
int index = Collections.binarySearch(list, list.get(i));
if (index != i) {
System.out.println("ERROR!");
}
}
return System.currentTimeMillis() - time;
}
}
运行结果
ArrayList访问消耗的时间:4
LinkedList访问消耗的时间:466
从上面可以明显看出arraylist的查询效率比linkendlist效率高很多,对于随机访问,ArrayList的访问速度更快。
ArrayList和LinkedList的插入数据耗时:
package com.example.demo.test1;
import java.util.*;
/**
* @program: test
* @description:
* @author: liulq
* @create: 2022-01-05 11:58
*/
public class Day3 {
static List array = new ArrayList();
static List linked = new LinkedList();
public static void main (String[]args){
for (int i = 0; i < 10000; i++) {
array.add(i);
linked.add(i);
}
System.out.println("ArrayList访问消耗的时间:" + insertTime(array));
System.out.println("LinkedList访问消耗的时间:" + insertTime(linked));
}
public static long insertTime (List list){
long time = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
list.add(10,i);
}
return System.currentTimeMillis() - time;
}
}
运行结果
ArrayList访问消耗的时间:28
LinkedList访问消耗的时间:2
可以看出,对于插入操作,LinkedList 的速度更快。
在空间复杂度上的区别
在LinkedList中有一个私有的内部类,定义如下:
private static class Entry {
Object element;
Entry next;
Entry previous;
}
LinkedList中的每一个元素中还存储了它的前一个元素的索引和后一个元素的索引。
ArrayList使用一个内置的数组来存储元素,这个数组的起始容量是10,当数组需要增长时,新的容量按如下公式获得:新容量 = 旧容量×1.5 + 1,也就是说每一次容量大概会增长50%
数据结构
ArrayList 是动态数组的数据结构实现,
而 LinkedList 是双向链表的数据结构实现。
数组:
链表:
单向链表
双向链表
数组与链表的优缺点:
数组
优点:
1、随机访问性强
2、查找速度快
缺点:
1、插入和删除效率低,必须移动数组
2、可能浪费内存
3、内存空间要求高,必须有足够的连续内存空间。
4、数组大小固定,不能动态拓展
链表
优点:
1、插入删除速度快,只需通过指针指向对象地址
2、内存利用率高,不会浪费内存
3、大小没有固定,拓展很灵活
缺点:
不能随机查找,必须从第一个开始遍历,查找效率低
总结:
(1)如果应用程序对数据有较多的随机访问,ArrayList对象要优于LinkedList对象,ArrayList和LinkedList都实现了List接口.
( 2 ) 如果应用程序有更多的插入或者删除操作,较少的随机访问,LinkedList对象要优于ArrayList对象;
(3)不过ArrayList的插入,删除操作也不一定比LinkedList慢,如果在List靠近末尾的地方插入,那么ArrayList只需要移动较少的数据,而LinkedList则需要一直查找到列表尾部,反而耗费较多时间,这时ArrayList就比LinkedList要快。
-
对于随机访问,ArrayList优于LinkedList,ArrayList可以根据下标以O(1)时间复杂度对元素进行随机访问。而LinkedList的每一个元素都依靠地址指针和它后一个元素连接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)
-
对于插入和删除操作,LinkedList优于ArrayList,因为当元素被添加到LinkedList任意位置的时候,不需要像ArrayList那样重新计算大小或者是更新索引。
4. LinkedList比ArrayList更占内存,因为LinkedList的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。