参考文献

LinkedList-JDK8

img

属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 元素个数
transient int size = 0;

/**
* 链表首节点
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node<E> first;

/**
* 链表尾节点
* Pointer to last node.
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
transient Node<E> last;

节点类

1
2
3
4
5
6
7
8
9
10
11
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;

Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* Constructs an empty list.
*/
public LinkedList() {
}

/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}

添加元素

  • 添加元素主要分为三种,添加在头部,添加在尾部,添加在中间三种.
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
53
54
55
56
57
58
59
60
61
62
63
/**
* Links e as first element.
*/
private void linkFirst(E e) {
// 首节点
final Node<E> f = first;
// 创建新的节点,新节点的next是首节点
final Node<E> newNode = new Node<>(null, e, f);
// 将首节点指向新节点
first = newNode;
if (f == null)
// 若首节点为空,说明当前元素为第一个元素,则同时将尾节点指向新节点
last = newNode;
else
// 否则将原首节点的prev指向新节点
f.prev = newNode;
// 元素个数增加1
size++;
modCount++;
}

/**
* Links e as last element.
*/
void linkLast(E e) {
// 尾节点
final Node<E> l = last;
// 创建新的节点,新的节点的prev是尾节点
final Node<E> newNode = new Node<>(l, e, null);
// 将尾节点指向新节点
last = newNode;
if (l == null)
// 若尾节点为空,说明当前元素为第一个元素,则同时将首节点指向新节点
first = newNode;
else
// 否则将原尾节点的next指向新节点
l.next = newNode;
size++;
modCount++;
}

/**
* Inserts element e before non-null Node succ.
*/
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
// succ是待添加节点的后继节点
// 找到待添加的前驱节点
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;
// 大小增加1
size++;
modCount++;
}

删除元素

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
* 删除首节点
* Unlinks non-null first node f.
*/
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
// 首节点的元素值
final E element = f.item;
// 首节点的next指针
final Node<E> next = f.next;
// 添加首节点的内容,协助GC
f.item = null;
f.next = null; // help GC
// 把首节点的next作为新的首节点
first = next;
// 如果只有一个元素,删除了,把尾节点也置为空
if (next == null)
last = null;
else
next.prev = null;
// 元素个数减1
size--;
modCount++;
return element;
}

/**
* 删除尾节点
* Unlinks non-null last node l.
*/
private E unlinkLast(Node<E> l) {
// assert l == last && l != null;
// 尾节点的元素值
final E element = l.item;
// 尾节点的前置指针
final Node<E> prev = l.prev;
// 清空尾节点的内容,帮助GC
l.item = null;
l.prev = null; // help GC
// 让前置节点成为新的尾节点
last = prev;
// 如果只有一个元素,删除了把首节点也置空
if (prev == null)
first = null;
else
prev.next = null;
// 元素个数减1
size--;
modCount++;
return element;
}

/**
* 删除指定节点
* Unlinks non-null node x.
*/
E unlink(Node<E> x) {
// assert x != null;
// x节点的值
final E element = x.item;
// x的后继节点
final Node<E> next = x.next;
// x的前驱节点
final Node<E> prev = x.prev;

if (prev == null) {
// 若前驱节点为空,则将首节点指向x的后继节点
first = next;
} else {
// 若前驱节点不为空,则将前驱节点的next指针指向x的后继节点
prev.next = next;
x.prev = null;
}

if (next == null) {
// 若后继节点为空,则将尾节点指向x的前驱节点
last = prev;
} else {
// 若后继节点不为空,则将后继节点的prev指针指向x的前驱节点
next.prev = prev;
x.next = null;
}

// 将要删除的元素置空
x.item = null;
// 元素个数减少1
size--;
modCount++;
return element;
}