1,底层是 双向链表 和 双端队列
2,可以添加 任意 重复 和 null 元素
3,线程不安全,没有实现同步
底层维护的是一个静态内部类
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;
}
}
LinkedList类的常见方法:
增
list.add("ycq");
调用了LinkedList 的Add()方法
public boolean add(E e) {
linkLast(e);
return true;
}
我们发现add(E e)方法右调用了一个无返回的方法void linkLast(E e),我们再查看这个方法的原码定义:
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++;
}
它做的工作就是将新元素放进新的小容器内(Noed对象),再将下表头指向一开始链表的最后一个元素,再将一开始链表的最后一个元素上表头指向新的小容器
我们再看一下小容器类(Noed)的构造器都做了什么吧。
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
这个小容器的构造器,把元素放进新建的小容器内,然后把这个小容器的上表头和下表头分别指向传进来的实参上。
删
list.remove("ycq02");
首先调用了方法boolean remove(Object o),进行删除操作。让我们看一下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;
}
进来先判断o等不等于空,等于空执行①,不等于空执行②
①,从前往后遍历,,如果找到空了,就调用方法:E unlink(Node<E> x)进行删除。
②,从前往后遍历,,如果找到o了,就调用方法:E unlink(Node<E> x)进行删除。
那么我们就来看看E unlink(Node<E> x)方法是怎么回事的吧。
E unlink(Node<E> x) {//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.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
这个方法做的工作就是将要删除的小容器的上下表头和元素指向都置空,并将要删除的小容器左右上下表头连接起来。