1 Introducción a LinkedList
1 LinkedList hereda AbstractSequentialList e implementa la interfaz List. Es la realización de una lista doblemente enlazada.
2 LinkedList implementa la interfaz Deque. Indica que el deque está implementado. Puede ser FIFO. También puede ser LIFO (último en entrar, primero en salir)
3 LinkedList implementa las interfaces Cloneable y Serializable, indicando que puede ser clonado. También se puede serializar.
2 Introducción a la propiedad
/**
* 元素的个数
*/
transient int size = 0;
/**
* 指向第一个结点的指针
*/
transient Node<E> first;
/**
* 指向最后一个结点的指针
*/
transient Node<E> last;
3 Estructura
//默认的构造器
public LinkedList() {
}
/**
* 构造一个包含元素的集合。
*/
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
4 Estructura de clases de nodo de lista enlazada
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;
}
}
5 Interpretación del código fuente
5.1 E getFirst () Obtiene el primer elemento
/**
* 获取第一个元素。直接将头指针赋值给当前结点,然后当前结点返回存储的数据item。如果为空,则报NoSuchElementException异常。
*/
public E getFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
5.2 E getLast () Obtiene el último elemento
/**
* 获取最后一个元素。直接将尾指针赋值给当前结点,然后当前结点返回存储的数据item。如果为空,则报NoSuchElementException异常。
*/
public E getLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
5.3 E removeFirst () elimina el primer elemento
/**
* 删除第一个元素。直接将头指针赋值给当前结点,然后解除结点之间的联系。调用unlinkFirst()方法接触引用
*/
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
Echemos un vistazo al método unlinkFirst ().
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;
//设置前驱为空。然后元素个数-1
if (next == null)
last = null;
else
next.prev = null;
size--;
//集合修改的次数。在迭代器迭代集合的时候使用
modCount++;
return element;
}
5.4 E removeLast () elimina el último elemento
public E removeLast() {
//将尾结点赋值给当前结点,然后解除尾结点的引用。
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
}
Llame a unlinkLast para liberar la referencia entre los nodos finales. Veamos la implementación de este método.
private E unlinkLast(Node<E> l) {
final E element = l.item;
//获取删除结点的前驱
final Node<E> prev = l.prev;
l.item = null;
l.prev = null; // 方法GC
//将前驱设置为尾结点
last = prev;
if (prev == null)
first = null;
else
prev.next = null;
size--;
modCount++;
return element;
}
5.5 addFirst (E e), addLast (E e) añadir elemento
//头插
public void addFirst(E e) {
linkFirst(e);
}
//尾插
public void addLast(E e) {
linkLast(e);
}
Llame a linkFirst y linkLast respectivamente para lograrlo. Veamos estos dos métodos.
private void linkFirst(E e) {
//获取头结点
final Node<E> f = first;
//创建结点。设置前驱为null。后继为f。也就是插入之前的头结点
final Node<E> newNode = new Node<>(null, e, f);
//将创建的新节点赋值给头结点。
first = newNode;
if (f == null)
//如果当前结点为空,那么新结点就是尾结点。
last = newNode;
else
//将新节点设置为当前结点的前驱
f.prev = newNode;
//元素个数+1
size++;
modCount++;
}
/**
* Links e as last element.
*/
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++;
}
5.6 booleano contiene (Objeto o) Determinar si se debe incluir un elemento
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
Llame al método indexOf () para lograrlo. Echemos un vistazo al método interno.
public int indexOf(Object o) {
int index = 0;
if (o == null) {
//遍历链表。如果当前对象为空,返回索引。
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
//遍历链表。如果当前对象equals结点元素,返回索引。
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
5.7 int size () Obtiene la longitud de la lista enlazada
public int size() {
return size;
}
5.8 elemento booleano agregar (E e) agregar
El predeterminado es el tapón de cola.
public boolean add(E e) {
linkLast(e);
return true;
}
5.9 booleano eliminar (Objeto o) eliminar elemento
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 {
//元素不为空的情况
//遍历链表,找到元素,然后解除链表结点之间的引用。调用了unlink来解除
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
El método de desvinculación elimina las referencias entre elementos. Eche un vistazo a este método.
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.prev = null;
}
//后继结点为空,表示为尾结点
if (next == null) {
//设置前驱为尾结点
last = prev;
} else {
//后继结点不为空。将删除元素的前驱设置为后继结点的前驱。后继结点设置为空
next.prev = prev;
x.next = null;
}
x.item = null;
//元素个数-1
size--;
modCount++;
return element;
}
5.10 clear () borra la colección.
Atraviese cada nodo y luego configure todos los elementos del nodo para que estén vacíos. Configure el nodo para que esté vacío. El número de elementos de la colección se establece en 0
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++;
}