LinkedList本质是一个双向链表,内部维护链表头节点和尾节点。Node是LinkedList的一个静态内部类,是LinkedList的核心,内部维护具体的值和上下节点的关系。
相对ArrayList增删效率高,查询效率低,线程不安全。
//集合大小
transient int size = 0;
//指向头节点
transient Node<E> first;
//指向尾节点
transient Node<E> last;
//无参构造函数
public LinkedList() {
}
//传入一个集合的构造函数
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
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;
}
}
//获取头节点的值,头节点为null抛出异常
public E getFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
//获取头节点,头节点为null时返回null
public E peekFirst() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
//获取尾节点的值
public E getLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
//获取尾节点的值,尾节点为null时返回null
public E peekLast() {
final Node<E> l = last;
return (l == null) ? null : l.item;
}
//删除头节点,并返回头节点的值,头节点为null时抛出异常
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
//删除头节点
return unlinkFirst(f);
}
//删除头节点
private E unlinkFirst(Node<E> f) {
//获取头节点的值
final E element = f.item;
//获取头节点的下一个节点
final Node<E> next = f.next;
//将头节点的值和下一个节点设为null
f.item = null;
f.next = null; // help GC
//将头节点指向下一个节点
first = next;
if (next == null)
//如果下一个节点为null,尾节点设为null
last = null;
else
//如果下一个节点不为null,将下一个节点的上一个节点设为null
next.prev = null;
//集合大小减1
size--;
//修改计数加1
modCount++;
//返回原头节点的值
return element;
}
//删除头节点,并返回头节点的值,头节点为null时返回null
public E pollFirst() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
//删除尾节点,并返回尾节点的值,尾节点为null时抛出异常
public E removeLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
//删除尾节点
return unlinkLast(l);
}
//删除尾节点
private E unlinkLast(Node<E> l) {
//获取尾节点的值
final E element = l.item;
//获取尾节点的上一个节点
final Node<E> prev = l.prev;
//将头节点的值和上一个节点的设为null
l.item = null;
l.prev = null; // help GC
//将尾节点指向上一个节点
last = prev;
if (prev == null)
//如果上一个节点为null,头节点设为null
first = null;
else
//如果上一个节点不为null,将上一个节点的下节点设为null
prev.next = null;
//集合大小减1
size--;
//修改计数加1
modCount++;
//返回原尾节点的值
return element;
}
//删除尾节点,并返回尾节点的值,尾节点为null时返回null
public E pollLast() {
final Node<E> l = last;
return (l == null) ? null : unlinkLast(l);
}
//添加头节点
public void addFirst(E e) {
//添加头节点
linkFirst(e);
}
//添加头节点
private void linkFirst(E e) {
//获取头节点的副本
final Node<E> f = first;
//创建新的头节点
final Node<E> newNode = new Node<>(null, e, f);
//头节点指向新节点
first = newNode;
if (f == null)
//如果原头节点为null,将尾节点指向新节点
last = newNode;
else
//如果原头节点不为null,将原头节点的上一个节点指向新节点
f.prev = newNode;
//集合大小加1
size++;
//修改计数加1
modCount++;
}
//添加尾节点
public void addLast(E e) {
//添加尾节点
linkLast(e);
}
//添加尾节点
void linkLast(E e) {
//获取尾节点的副本
final Node<E> l = last;
//创建新的尾节点
final Node<E> newNode = new Node<>(l, e, null);
//尾节点指向新节点
last = newNode;
if (l == null)
//如果尾节点为null,头节点指向新节点
first = newNode;
else
//如果尾节点不为null,原尾节点的下一个节点指向新节点
l.next = newNode;
//集合大小加1
size++;
//修改计数加1
modCount++;
}
//在集合末尾添加一个元素
public boolean add(E e) {
linkLast(e);
return true;
}
//在指定位置添加一个元素
public void add(int index, E element) {
//检查下标
checkPositionIndex(index);
if (index == size)
//若下标等于size,直接添加尾节点
linkLast(element);
else
//在指定位置添加节点
linkBefore(element, node(index));
}
//在指定节点前添加元素
void linkBefore(E e, Node<E> succ) {
//获取指定节点的上一个节点
final Node<E> pred = succ.prev;
//创建新节点
final Node<E> newNode = new Node<>(pred, e, succ);
//指定节点的上一个节点指向新节点
succ.prev = newNode;
if (pred == null)
//若指定节点的上一个节点为null,头节点指向新节点
first = newNode;
else
//若指定节点的上一个节点不为null,则指定节点的下一个节点指向新节点
pred.next = newNode;
//集合大小加1
size++;
//修改计数加1
modCount++;
}
//删除第一个元素
public E remove() {
return removeFirst();
}
//删除指定下标的元素
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
//删除指定值的元素
public boolean remove(Object o) {
if (o == null) {
//若该对象为null,使用==比较
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
//若该对象不为null,使用equals比较
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
//删除指定元素,并返回值
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) {
//上节点为null,说明该元素是头节点
//头节点指向下一个节点
first = next;
} else {
//上节点的下节点指向下一个节点
prev.next = next;
//指定元素的上节点设为null
x.prev = null;
}
if (next == null) {
//下节点为null,说明该元素是尾节点
last = prev;
} else {
//下节点的上一个节点指向上节点
next.prev = prev;
//该元素的下节点设为null
x.next = null;
}
//该元素的值设为null
x.item = null;
//集合大小减1
size--;
//修改计数加1
modCount++;
//返回该元素的值
return element;
}
//在末尾添加集合元素
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
//在指定位置添加集合元素
public boolean addAll(int index, Collection<? extends E> c) {
//检查下标
checkPositionIndex(index);
//集合转数组
Object[] a = c.toArray();
//获取数组长度
int numNew = a.length;
if (numNew == 0)
return false;
//pred表示添加位置的前一个节点
//succ表示添加位置的节点
Node<E> pred, succ;
if (index == size) {
//若index等于size,说明在尾部添加
//succ设为null,pred指向原尾元素
succ = null;
pred = last;
} else {
//sucss指向当前元素,pred执行当前元素的上节点
succ = node(index);
pred = succ.prev;
}
//遍历数组
for (Object o : a) {
E e = (E) o;
//创建新节点
Node<E> newNode = new Node<>(pred, e, null);
if (pred == null)
//若上一个节点为null,说明在下标为首节点的的位置,则头节点指向新节点
first = newNode;
else
//上一个节点的下节点指向新节点
pred.next = newNode;
//pred指向下一个新节点
pred = newNode;
}
//循环结束后
if (succ == null) {
//若succ为null,说明最后的节点是尾节点
last = pred;
} else {
//最后新建节点的下节点指向succ
pred.next = succ;
//succ的上节点指向最后新建节点
succ.prev = pred;
}
//集合数量加numNew
size += numNew;
//修改计数加1
modCount++;
return true;
}
//获取指定位置的元素
Node<E> node(int index) {
if (index < (size >> 1)) {
//指定位置小于总大小的一半,从头节点开始遍历
//获取头节点
Node<E> x = first;
//遍历到指定index
for (int i = 0; i < index; i++)
x = x.next;
//返回元素
return x;
} else {
//指定位置大于总大小的一半,从尾节点开始遍历
//获取尾节点
Node<E> x = last;
//遍历到指定index
for (int i = size - 1; i > index; i--)
x = x.prev;
//返回元素
return x;
}
}
//清空集合
public void clear() {
//遍历所有元素
for (Node<E> x = first; x != null; ) {
//保存下一个节点的副本
//将遍历到的元的值、上节点、下节点设为null
Node<E> next = x.next;
x.item = null;
x.next = null;
x.prev = null;
x = next;
}
//将头节点和尾节点设为null
first = last = null;
//集合大小设为0
size = 0;
//修改计数加1
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;
x.item = element;
return oldVal;
}
//克隆
//LinkedList的clone属于浅拷贝,只拷贝对象的引用
public Object clone() {
//生产新的集合对象
LinkedList<E> clone = superClone();
//初始化状态
clone.first = clone.last = null;
clone.size = 0;
clone.modCount = 0;
//遍历原集合,将元素添加如新集合中
for (Node<E> x = first; x != null; x = x.next)
clone.add(x.item);
return clone;
}
//集合转数组
public Object[] toArray() {
//创建新数组
Object[] result = new Object[size];
int i = 0;
//遍历集合,并向数组添加元素
for (Node<E> x = first; x != null; x = x.next)
result[i++] = x.item;
return result;
}
//将列表转为指定数组
public <T> T[] toArray(T[] a) {
//数组的长度小于集合的size,重新构建数组的长度
if (a.length < size)
a = (T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
int i = 0;
Object[] result = a;
//遍历集合,对数组赋值
for (Node<E> x = first; x != null; x = x.next)
result[i++] = x.item;
//若数组的长度大于size,在下标为size的位置设为null
if (a.length > size)
a[size] = null;
return a;
}
//是否包含该对象
public boolean contains(Object o) {
return indexOf(o) != -1;
}
//获取该对象的下标
public int indexOf(Object o) {
int index = 0;
if (o == null) {
//该对象为null,使用==比较
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
//该对象不为null,用equals比较
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
//不存在则返回-1
return -1;
}
//获取集合大小
public int size() {
return size;
}