先说List
- List存储对象可重复,与Set对立,Set不可重复
- List与Set都继承Collection接口
提前说结论
- ArrayList (动态数组),所以查询快,增删慢,线程同步不安全
- LinkedList(双向链表),查询慢,增删快
- Vector(动态数组),crud都慢,被ArrayList替代。线程异步安全
- Stack(堆栈),继承于Vector,先进后出
List基本操作
- 插入 add()
- 查找 get()
- 删除 remove(int index)
- 修改 set()
- 清空 clear()
- 遍历 Iterator
针对性能使用java代码测试
import java.util.ArrayList;
import java.util.LinkedList;
public class TestStack {
public static void main(String[] args) {
testArrayList();
testLinkedList();
/* 执行结果
ArrayList add cost time :37901
ArrayList get cost time :0
ArrayList remove cost time :37149
LinkedList add cost time :16
LinkedList get cost time :1436
LinkedList remove cost time :0
*/
}
private static void testArrayList(){
ArrayList<String> list=new ArrayList<String>();
int maxTestCount=80*10000;
//测试添加
long start =System.currentTimeMillis();
for(int i =0;i<maxTestCount;i++){
list.add(0,String.valueOf(i));
}
long end =System.currentTimeMillis();
System.out.println("ArrayList add cost time :"+(end-start));//5100
//测试查询
start =System.currentTimeMillis();
for(int i =0;i<maxTestCount;i++){
list.get(i);
}
end =System.currentTimeMillis();
System.out.println("ArrayList get cost time :"+(end-start));//15
//测试删除
start =System.currentTimeMillis();
for(int i =maxTestCount;i>0;i--){
list.remove(0);
}
end =System.currentTimeMillis();
System.out.println("ArrayList remove cost time :"+(end-start));//5800
}
private static void testLinkedList(){
LinkedList<String> list=new LinkedList<String>();
int maxTestCount=50000;
//测试添加
long start =System.currentTimeMillis();
for(int i =0;i<maxTestCount;i++){
list.add(0,String.valueOf(i));
}
long end =System.currentTimeMillis();
System.out.println("LinkedList add cost time :"+(end-start));//1500
//测试查询
start =System.currentTimeMillis();
for(int i =0;i<maxTestCount;i++){
list.get(i);
}
end =System.currentTimeMillis();
System.out.println("LinkedList get cost time :"+(end-start));//1500
//测试删除
start =System.currentTimeMillis();
for(int i =maxTestCount;i>0;i--){
list.remove(0);
}
end =System.currentTimeMillis();
System.out.println("LinkedList remove cost time :"+(end-start));
}
}
ArrayList添加元素的原理
ArrayList是一个可变长数组,插入数据时,则需要先将原始数组中的数据复制到一个新的数组,随后再将数据赋值到新数组的指定位置(如下图);删除数据时,也是将原始数组中要保留的数据复制到一个新的数组

LinkedList添加元素的原理
既然LinkedList是一个由相互引用的节点组成的双向链表,那么当把数据插入至该链表某个位置时,该数据就会被组装成一个新的节点,随后只需改变链表中对应的两个节点之间的引用关系,使它们指向新节点,即可完成插入(如下图);同样的道理,删除数据时,只需删除对应节点的引用即可。

因此,在添加或删除数据的时候,ArrayList经常需要复制数据到新的数组,而LinkedList只需改变节点之间的引用关系,这就是LinkedList在添加和删除数据的时候通常比ArrayList要快的原因