ArrayList 与 LinkedList

摘要

  • 与vector(线程安全) 一起都是list的子类
  • ArrayList基于数组的数据结构 LinkedList基于双向链表的数据结构
  • ArrayList 查询时直接返回数据,LinkedList需要遍历链表,所以在随机查询中ArrayList效率比较高
  • ArrayList 在增删时需要移动元素的位置,需要进行数组的copy,LinkedList需要根据位置查到插入位置的元素,然后再进行添加指针,在数据量比较小时(10000以下)时性能差不多,但是数据量较大时LinkedList效率比较高

1.与vector(线程安全) 一起都是list的子类

List JDK文档描述

2.ArrayList基于数组的数据结构 LinkedList基于双向链表的数据结构

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
复制代码   // ArrayList
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
//LinkedList
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index);

Object[] a = c.toArray();
int numNew = a.length;
if (numNew == 0)
return false;

Node<E> pred, succ;
if (index == size) {
succ = null;
pred = last;
} else {
succ = node(index);
pred = succ.prev;
}

for (Object o : a) {
@SuppressWarnings("unchecked") E e = (E) o;
Node<E> newNode = new Node<>(pred, e, null);
if (pred == null)
first = newNode;
else
pred.next = newNode;
pred = newNode;
}

if (succ == null) {
last = pred;
} else {
pred.next = succ;
succ.prev = pred;
}

size += numNew;
modCount++;
return true;
}

3.ArrayList 查询时直接返回数据,LinkedList需要遍历链表,所以在随机查询中ArrayList效率比较高

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
复制代码    //ArrayList
public E get(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

return (E) elementData[index];
}
//LinkedList
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}


Node<E> node(int index) {
// assert isElementIndex(index);

if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}

4.ArrayList 在增删时需要移动元素的位置,需要进行数组的copy,LinkedList需要根据位置查到插入位置的元素,然后再进行添加指针,在数据量比较小时(10000以下)时性能差不多,但是数据量较大时LinkedList效率比较高

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
复制代码    //ArrayList
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}

//LinkedList
public void add(int index, E element) {
checkPositionIndex(index);

if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}

void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}

5.测试程序

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
复制代码public class Test1 {
static List<Integer> arrayData =new ArrayList<Integer>();
static List<Integer> linkedData =new LinkedList<Integer>();
public static int maxCount = 30000;

public static void main(String[] args) {

for(int i=0;i<maxCount;i++){
arrayData.add(i);
linkedData.add(i);
}
System.out.println("maxCount:"+maxCount);
//获得两者随机访问的时间
System.out.println("arrayData get time:"+getTime(arrayData));
System.out.println("linkedData get time:"+getTime(linkedData));
//获得两者插入数据的时间
System.out.println("arrayData insert time:"+insertTime(arrayData));
System.out.println("linkedData insert time:"+insertTime(linkedData));

}
//获取数据
public static long getTime(List<Integer> list){
long time=System.currentTimeMillis();
for(int i = 0; i < maxCount; i++){
int getData = list.get(i);
}
return System.currentTimeMillis()-time;
}

//插入数据
public static long insertTime(List<Integer> list){
long num = maxCount;
int index = 1000;
long time=System.currentTimeMillis();
for(int i = 1; i < num; i++){
list.add(index, i);
}
return System.currentTimeMillis()-time;
}

}

6.运行结果

1
2
3
4
5
6
7
8
9
10
11
复制代码maxCount:10000
arrayData get time:1
linkedData get time:82
arrayData insert time:24
linkedData insert time:27

maxCount:30000
arrayData get time:2
linkedData get time:658
arrayData insert time:127
linkedData insert time:58

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%