ArrayList vs. LinkedList vs. Vector

1. List概览 html

List,就像它的名字暗示的同样,是一组排列有序的元素。当咱们讨论List的时候,很容易将它和Set做比较。Set是一组惟一的并且排列无序的元素。 java

下图是集合类的层次结构图。你能够整体上知道咱们今天讨论的主题。 程序员

2. ArrayList vs. LinkedList vs. Vector

从上图可知,它们都实现了List接口。它们的用法差很少,主要的区别在于它们对于不一样操做的操做速度不一样。 数组

ArrayList是能够改变大小的数组。当有元素添加到ArrayList中去时,它的大小动态的增长。元素能够直接经过get()和set()方法进行访问,由于ArrayList其实是数组。LinkedList是个双向链表。它的add()和remove()方法比ArrayList快,可是get()和set()方法却比ArrayList慢。Vector和ArrayList相似,可是Vector是同步的。若是在线程安全的环境下,使用ArrayList是更好的选择。添加元素的时候,当超过初始容量的时候,Vector和ArrayList须要更多的空间:Vector须要将数组的大小增长一倍,而ArrayList须要增长50%。 安全

LinkedList还实现了Queue接口,这样就比ArrayList和Vector多出了一些方法如offer(), peek(), poll()等。 性能

注意:ArrayList的初始容量(initial capacity)很小。咱们应该设置一个比较大的初始容量,这样能够避免从新改变大小。 测试

3. ArrayList的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
ArrayList al =newArrayList();
al.add(3);
al.add(2);     
al.add(1);
al.add(4);
al.add(5);
al.add(6);
al.add(6);
 
Iterator iter1 = al.iterator();
while(iter1.hasNext()){
    System.out.println(iter1.next());
}

4. LinkedList的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
LinkedList ll =newLinkedList();
ll.add(3);
ll.add(2);     
ll.add(1);
ll.add(4);
ll.add(5);
ll.add(6);
ll.add(6);
 
Iterator iter2 = ll.iterator();
while(iter2.hasNext()){
    System.out.println(iter2.next());
}

由上可见,它们的用法相同,主要的区别在于它们内部的实现,以及操做的复杂度的不一样。 spa

5. Vector

Vector几乎和ArrayList相等,主要的区别在于Vector是同步的。正由于此,Vector比ArrayList的开销更大。一般大部分程序员都使用ArrayList,他们能够本身写代码进行同步。 线程

6. ArrayList vs. LinkedList的性能比较

时间复杂度以下: htm

* 表中的add()指的是add(E e)(便是在列表末尾添加元素),remove()方法指的是remove(int index)。

ArrayList对于任意索引的插入/删除操做的时间复杂度是O(n),而在列表的尾部的操做时间为O(1)。

LinkedList对于任意索引的插入/删除操做的时间复杂度是O(n),而在列表的头部或尾部的操做时间为O(1)。

(译者注:这里原文解释的不是太清楚。对于任意索引的插入/删除操做

Arrays:

  • 找到插入/删除位置的时间复杂度是O(1)
  • 进行插入/删除操做的时间复杂度是O(n)

Linked Lists:

  • 找到插入/删除位置的时间复杂度是O(n)
  • 进行插入/删除操做的时间复杂度是O(1)

我使用下面的代码测试它们的性能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
ArrayList arrayList =newArrayList();
LinkedList linkedList =newLinkedList();
 
// ArrayList add
longstartTime = System.nanoTime();
 
for(inti =0; i <100000; i++) {
    arrayList.add(i);
}
longendTime = System.nanoTime();
longduration = endTime - startTime;
System.out.println("ArrayList add:  "+ duration);
 
// LinkedList add
startTime = System.nanoTime();
 
for(inti =0; i <100000; i++) {
    linkedList.add(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("LinkedList add: "+ duration);
 
// ArrayList get
startTime = System.nanoTime();
 
for(inti =0; i <10000; i++) {
    arrayList.get(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("ArrayList get:  "+ duration);
 
// LinkedList get
startTime = System.nanoTime();
 

for(inti =0; i <10000; i++) {     

    linkedList.get(i); 

endTime = System.nanoTime(); 

duration = endTime - startTime; 

System.out.println("LinkedList get: "+ duration);

// ArrayList remove 

startTime = System.nanoTime(); 

for (int i = 9999; i >=0; i--) {

    arrayList.remove(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("ArrayList remove:  "+ duration);
 
// LinkedList remove
startTime = System.nanoTime();
 
for(inti =9999; i >=0; i--) {
    linkedList.remove(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("LinkedList remove: "+ duration);

输出以下:

1
2
3
4
5
6
ArrayList add:  13265642
LinkedList add: 9550057
ArrayList get:  1543352
LinkedList get: 85085551
ArrayList remove:  199961301
LinkedList remove: 85768810

它们的性能的差异很显著。LinkedList对于add()和remove()相对于ArrayList要快,可是get()要慢些。按照复杂度以及测试结果来看,咱们很容易知道何时该使用ArrayList,何时该使用LinkedList。简而言之,下面的状况该使用LinkedList:

  • 若是没有大量的随机访问
  • 若是有不少add/remove的操做
相关文章
相关标签/搜索