Linkedlist概述
Linkedlist和Arraylist一样都实现了list接口,但是Linkedlistd的底层是链表实现,相比Arraylist,长于增删元素,但是随机访问效率比不上基于数组实现的Arraylist。
源码剖析
定义
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
继承了AbstractSequentialList接口,减少了实现List接口的代码复杂度。
节点
transient int size = 0;
transient Node<E> first;
transient Node<E> last;
//Node<E>的实现是Linkedlist内部类
//典型双向链表实现
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;
}
}
构造方法
无参构造:
public LinkedList() { header.next = header.previous = header; }
构造包含collection元素的:
public LinkedList(Collection<? extends E> c) { this(); addAll(c); }
Add
添加到指定位置
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
void linkLast(E e) {
final Node<E> l = last;
//新建一个节点,前节点为I,后节点为null
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
void linkBefore(E e, Node<E> succ) {
//创建前节点,用来判断succ的前节点是否为空而已
final Node<E> pred = succ.prev;
//创建新节点,插入到前节点和后节点之间
final Node<E> newNode = new Node<>(pred, e, succ);
//真正将新节点赋给succ的前节点。之前的那个赋值只是为了判断succ的前节点是否为空,相当于一个temp
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
Remove
查找特定元素
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
//删除元素
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
//删除元素
unlink(x);
return true;
}
}
}
return false;
}
//unlink实现
E unlink(Node<E> x) {
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
//如果prev为null
//又因为要删除x元素,所以直接将next指向first
if (prev == null) {
first = next;
} else {
//如果prev不为null
//又因为要删除x元素,将next指向prev.next,跳过x节点
prev.next = next;
x.prev = null;
}
//与上面同理
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}