一、概述
上图为LinkedList的继承结构图,根据继承关系总结如下:
LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
LinkedList 实现 List 接口,能对它进行队列操作。
LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
LinkedList 是非同步的。
二、源码分析
1、成员变量
//集合元素数量
transient int size = 0;
//链表头结点
transient Node<E> first;
//链表尾结点
transient Node<E> last;
LinkedList的属性不多,size表示其元素数量,first表示链表头节点,而last表示链表尾节点。其中链表是由节点(Node)组成的,源码如下:
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;
}
}
结点(Node)为LinkedList的静态内部类,且有前置节点和后置节点 ,只是头节点的前置节点为空,而尾节点的后置节点为空,说明LinkedList内部为双向链表结构。可以用如下的图形象的表示:
2、构造方法
//默认构造方法
public LinkedList() {
}
//通过集合c的元素构造链表
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);//将集合c中的所有元素添加到LinkedList中
}
不传参的构造方法创建空的链表,将集合作为入参的构造方法则通过集合c的元素创建链表,调用了addAll方法,addAll方法的原理将在下面讲解。
3、常用方法
我们从LinkedList集合的常用操作入手,比如集合的增删改查,栈的进栈和出栈,队列的进队列和出队列等。
3.1、增
方法名 | 功能 |
---|---|
linkFirst(E e) | 添加元素e到链表的头部 |
linkLast(E e) | 添加元素e到链表的尾部 |
addFirst(E e) | 添加元素e到链表的头部,调用 linkFirst方法,无返回值 |
addLast(E e) | 添加元素e到链表的尾部,调用linkLast方法,无返回值 |
add(E e) | 添加元素e到链表的尾部,调用linkLast方法 |
add(int index, E element) | 添加元素e到链表的指定位置index处 |
offer(E e) | 添加元素e到链表的尾部,调用 add(E e) 方法 |
offerFirst(E e) | 添加元素e到链表的头部,调用 addFirst(E e)方法,返回true或false |
offerLast(E e) | 添加元素e到链表的尾部,调用 addLast(E e)方法,返回true或false |
addAll(Collection<? extends E> c) | 添加集合c的所有元素到链表的尾部 |
addAll(int index, Collection<? extends E> c) | 添加集合c的所有元素到链表的指定位置 处 |
linkBefore(E e, Node succ) | 将元素e插入到链表的指定节点succ前 |
push(E e)(E e, Node succ) | 将元素e插入到栈上,无返回值,其实就是调用了addFirst(E e)方法 |
有上面的表格可知,只要理解了linkFirst&