public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
复制代码
//节点
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;
}
}
transient int size = 0;//集合大小(节点个数)
transient Node<E> first;//表头
transient Node<E> last;//表尾
//空链表
public LinkedList() {
}
//包含Collection元素的
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
//插入到表头,参数e作为表头,原表头
private void linkFirst(E e) {
final Node<E> f = first;//当前链表的表头
final Node<E> newNode = new Node<>(null, e, f);//创建新节点,当前节点为参数e,next节点为当前表头,前驱null
first = newNode;//新节点作为当前链表的表头
if (f == null)//如果表头是空的,说明是空表。
last = newNode;//表尾指向新节点
else
f.prev = newNode;//非空表,原表头的指向新节点
size++;
modCount++;
}
//添加到表尾
void linkLast(E e) {
final Node<E> l = last;//当前链表的表尾
final Node<E> newNode = new Node<>(l, e, null);//创建新节点,表尾作为新节点的“前驱”,e是当前节点,后继指向null
last = newNode; //记录新节点为表尾
if (l == null) //如果表尾为空,说明空表
first = newNode;//放到表尾
else
l.next = newNode;//原表尾节点后继指向当前新节点
size++;
modCount++;
}
//节点e插入到节点succ之前
void linkBefore(E e, Node<E> succ) {
final Node<E> pred = succ.prev;//succ节点的前驱
final Node<E> newNode = new Node<>(pred, e, succ); //创建新节点,newNode前驱指向pred,当前节点e,后继节点指向succ
succ.prev = newNode; //succ节点前驱指向newNode,也就是e在succ前面
if (pred == null) //如果succ前面是空的,说明succ是表头
first = newNode; //新节点作为表头
else
pred.next = newNode;//e前面的节点后继 指向newNode。
size++;
modCount++;
}
//删除链表首节点
private E unlinkFirst(Node<E> f) {
final E element = f.item;//当前节点
final Node<E> next = f.next;//后继节点
f.item = null;//当前节点删除
f.next = null; // 后继引用删除
first = next;//第一个节点删除后,第二节点作为表头
if (next == null)//next节点是空,说明只有一个节点。
last = null;//表尾置空
else
next.prev = null;//表头没有前驱
size--;
modCount++;
return element;
}
//删除尾节点
private E unlinkLast(Node<E> l) {
final E element = l.item;//当前节点
final Node<E> prev = l.prev;//当前节点的前驱
l.item = null;//删除当前节点
l.prev = null; //help gc
last = prev;//尾节点的前面一个作为表尾
if (prev == null)//前面没有,说明只有一个节点
first = null;//置空表头
else
prev.next = null;//尾节点没有下一个节点。
size--;
modCount++;
return element;
}
//删除一个节点
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;//当前节点
final Node<E> next = x.next;//后继
final Node<E> prev = x.prev;//前驱
if (prev == null) {//没有前驱,说明删除的是首节点。
first = next;//后继成为表头
} else {
prev.next = next;//前驱的后继 指向当前x节点的后继
x.prev = null;///删除当前x节点前驱
}
if (next == null) {//x节点后继是空,说明是尾节点
last = prev;/前驱成为表尾
} else {
next.prev = prev;//后继的前驱 指向 x节点的前驱
x.next = null;//删除后继
}
x.item = null;//删除x节点
size--;
modCount++;
return element;
}
//获取表头
public E getFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
//获取表尾
public E getLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
//移除表头
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);//这个方法上面已经分析过
}
//移除表尾
public E removeLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
}
//添加到表头
public void addFirst(E e) {
linkFirst(e);
}
//添加到表尾
public void addLast(E e) {
linkLast(e);
}
//判断是否包含
public boolean contains(Object o) {
return indexOf(o) != -1;
}
//找到对象o的索引。
public int indexOf(Object o) {
int index = 0;
if (o == null) {//找到等于null
for (Node<E> x = first; x != null; x = x.next) {//不停读取next节点
if (x.item == null)
return index;
index++;
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
//链表大小
public int size() {
return size;
}
//添加节点到尾部
public boolean add(E e) {
linkLast(e);
returntrue;
}
//遍历找到这个元素删除,成功返回true,否则false;
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
returntrue;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
returntrue;
}
}
}
returnfalse;
}
//批量添加
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
//从index开始批量插入
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index);//越界检查
Object[] a = c.toArray();//调用实现类的toArray()方法,转成数组
int numNew = a.length;//数组长度
if (numNew == 0)//如果参数c长度为0,说明空集合,直接返回添加失败。
returnfalse;
Node<E> pred, succ;//pred是succ的前驱,succ是index位置的节点
if (index == size) {//从表尾插入
succ = null;
pred = last;//当前链表的表尾放到前驱pred
} else {
succ = node(index);//折半找到index位置的元素
pred = succ.prev;//succ的前驱
}
for (Object o : a) {//创建小链表
E e = (E) o;//元素
Node<E> newNode = new Node<>(pred, e, null);//创建一个节点,前驱指向succ节点前驱
if (pred == null)//如果没有前驱,说明是表头
first = newNode;//新节点作为表头
else
pred.next = newNode;//新节点指向要插入位置节点的前驱,前驱的后继再指向新节点
pred = newNode;//前驱节点指针向后移,下一个节点的前驱就是newNode。
}
if (succ == null) {//从表尾插入
last = pred;//指向最后一个插入的节点
} else {
pred.next = succ;//最后一个节点跟原来succ节点相连
succ.prev = pred;
}
size += numNew;
modCount++;
returntrue;
}
//折半查找
Node<E> node(int index) {
if (index < (size >> 1)) {//size右移相当于除以2的1次方,index小于size一半
Node<E> x = first;
for (int i = 0; i < index; i++)//一直向下找到index位置的元素
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
//清除所有节点
public void clear() {
for (Node<E> x = first; x != null; ) {
Node<E> next = x.next;
x.item = null;
x.next = null;
x.prev = null;
x = next;
}
first = last = null;
size = 0;
modCount++;
}
//折半查找节点
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
//更新节点
public E set(int index, E element) {
checkElementIndex(index);//越界检查
Node<E> x = node(index);//折半查找节点
E oldVal = x.item;//index节点的值
x.item = element;//重新赋值
return oldVal;//返回之前修改的值
}
//插入节点
public void add(int index, E element) {
checkPositionIndex(index);//越界检查
if (index == size)//从尾部插入
linkLast(element);
else//插入到之前
linkBefore(element, node(index));
}
//插入到succ之前
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;//succ前驱节点
final Node<E> newNode = new Node<>(pred, e, succ);//新节点的前驱指向succ的前驱,新节点后继指向succ
succ.prev = newNode;//succ的前驱指向新节点
if (pred == null)//空表判断
first = newNode;
else
pred.next = newNode;//succ的前驱节点 后继指向新节点
size++;
modCount++;
}
//移除节点
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));//折半找到后删除
}
//删除x节点
E unlink(Node<E> x) {
final E element = x.item;//要删除的节点
final Node<E> next = x.next;//后继
final Node<E> prev = x.prev;/前驱
if (prev == null) {//如果前驱是空的,说明x是表头
first = next;//后继作为表头
} else {
prev.next = next;//x的前驱的后继 指向x的后继
x.prev = null;//移除x前驱引用
}
if (next == null) {//表尾?
last = prev;//x前驱作为表尾
} else {
next.prev = prev;//下后继的前驱 指向x的前驱
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
//从表尾找到对象(反向查找)
public int lastIndexOf(Object o) {
int index = size;
if (o == null) {
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (x.item == null)
return index;
}
} else {
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (o.equals(x.item))
return index;
}
}
return -1;
}
//返回表头
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
//返回表头
public E element() {
return getFirst();
}
//删除并返回表头
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
复制代码