文章目录
1. 概述
- 双向链表实现,允许null值
- 未实现同步,所以在多线程的情况下,可能会出现错误,需要在外部进行同步
- 如果需要遍历链表,建议使用 iterator迭代器,因为使用get(index)每次需要从头结点或尾结点开始遍历,非常消耗时间。LinkedList提供了两种迭代器,一种是指提供向后遍历的Iterator,另一种是List的专有迭代器ListIterator。
- 删除效率较高,插入访问效率比较低
2. 继承或实现
public class LinkedList\<E> extends AbstractSequentialList\<E> implements List\<E>, Deque\<E>, Cloneable, java.io.Serializable
- 继承AbstractSequentialList
- 实现了Cloneable接口,它支持克隆
- 实现了Deque(队列)接口,实现了Deque所有的可选的操作
- 实现java.io.Serializable,序列化,能够保存在内存中,在网络之间传输,进行反序列化就能获得序列化前的对象
3. 成员变量
//节点个数
transient int size = 0;
//指向头结点
transient Node<E> first;
//指向尾结点
transient Node<E> last;
//用内部类表示节点
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;
}
}
3. 构造器
//无参构造器
public LinkedList() {
}
//将集合c中的元素添加至新的LinkedList
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
4. 方法
4.1 add
//返回当前链表的长度,即元素的个数
public int size() {
return size;
}
//是否包含参数o
public boolean contains(Object o) {
return indexOf(o) != -1;
}
//添加元素,尾插法,和addLast方法是等效的
public boolean add(E e) {
linkLast(e);
return true;
}
//linkLast实现
void linkLast(E e) {
//l指向尾结点
final Node<E> l = last;
//创建新的节点,通过构造器就已经把新节点添加到链表里面了
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
//尾结点为空表示当前链表为空,插入的元素为第一个元素
if (l == null)
first = newNode;
//不是将尾结点和新节点连接起来
else
l