LinkedList源码分析
LinkedList集合源码分析
- 底层数据结构是双链表
- 特点是:查询慢,增删快,但是如果操作的是首尾元素,速度也是极快
底层数据结构是双链表,查询慢,首尾操作的速度是极快的,所以多了很多首尾操作的API。
特有方法 说明
public void addFirst(E e) 在该列表的开头插入指定的元素
public void addLast(E e) 将指定的元素追加到此列表的末尾
public E getFirst() 返回此列表中的第一个元素
public E getLast() 返回此列表中的最后一个元素
public E removeFirst() 从此列表中删除并返回第一个元素
public E removeLast() 从此列表中删除并返回最后一个元素
首先,先把源码重要部分扒取下来
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;
}
}
这一部分是属于
java.util.LinkedList包下,同时也是LinkedList的内部类,Node代表的就是结点的对象
分析这三个成员变量
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;
}
每创建一个节点,就要把那三个数据传递过来才可以
接下来又来看这段源码
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
/**
* Pointer to first node.
*/
transient Node<E> first;
/**
* Pointer to last node.
*/
transient Node<E> last;
/*
void dataStructureInvariants() {
assert (size == 0)
? (first == null && last == null)
: (first.prev == null && last.next == null);
}
*/
/**
* Constructs an empty list.
*/
public LinkedList() {
}
transient int size = 0;
/**
* Pointer to first node.
*/
transient Node<E> first;
/**
* Pointer to last node.
*/
transient Node<E> last;
在LinkedList源码中发现这里有三个成员变量
第一个size=0,这里不仅表达了结点个数,也表示了集合长度
第二和第三分别表示了头结点和尾结点
然后就是空参构造,也就是说,当我们使用空参构造的时候,前面三个成员变量就会随之加载进来
接下来我们来一段代码看看执行流程:
LinkedList<String> list=new LinkedList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
我们直接调用add方法添加"aaa",进入源码
public boolean add(E e) {
linkLast(e);
return true;
}
又进入linkLast()方法
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
这里我就使用图片演示了
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;
}
}