本章分析List系列中的LinkedList,真正意义上的链表,底层采用链表形式存储数据元素。LinkedList是一个双向链表,可以向前或向后两个方向遍历链表。LinkedList也可以存放null元素。
一、 类实现/继承体系结构
为了对整个List实现/继承体系有个全貌,先将体系结构图画出来:
二、 关键数据成员
(1)节点类
private static classNode<E>,包含标准的双向链表节点结构:元素、指向前一个元素的引用和指向下一个元素的引用。
(2)首尾节点
为了更便利的操作链表,比如在链表末尾添加删除元素,LinkedList提供了首尾两个节点引用:
transient Node<E>first;
transient Node<E>last;
(3)链表存放的元素个数
transient int size = 0;
三、 构造函数
LinkedList提供了两种形式的构造函数:
publicLinkedList ()
publicLinkedList (Collection<? extends E> c):利用另一个集合初始化LinkedList,要求就是负责初始化集合中的元素类型是E或者是E的子类。
四、 增
(1) void addFirst(E e):将值为e的元素加入到链表头部,会调用linkFirst:
private voidlinkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null,e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
(2) void addLast(E e):将值为e的元素加入到链表尾部,跟addFirst类似,只是将元素加到链表尾部;
(3) boolean add(E e):默认加到链表的末尾,linkLast(e);
(4) boolean addAll(Collection<? extends E> c)与
booleanaddAll(int index, Collection<? extends E> c)都是将容器c中的元素添加到链表中,不带index的接口,默认加到链表尾部,所以实现也是调用带index的接口:
publicboolean addAll(Collection<? extends E> c) {
returnaddAll(size, c);
}
(5) boolean offer(E e):添加到链表尾部,同offerLast
(6) boolean offerFirst(E e):添加到链表头部
五、 删
(1) E removeFirst():删除链表第一个元素,首先判断first是否合法,然后调用unlinkFirst:
private EunlinkFirst(Node<E> f) {
// assert f == first && f !=null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
(2) E removeLast():删除最后一个元素,与removeFirst类似,调用unlinkLast实现删除最后一个元素;
(3) boolean remove(Object o)
(4) public E poll():返回并删除第一个元素;
(5) public E remove():删除第一个元素;
(6)
六、 改
(1) E set(int index, E element):设置index位置的元素值
七、 查
(1) E getFirst():获取第一个元素;
(2) E getLast():获取最后一个元素;
(3) boolean contains(Object o):是否包含元素o,使用indexOf函数判断,不包含返回-1;
(4) public E peek():返回第一个元素,如果链表为空,返回null;
(5) public E element():返回第一个元素,如果链表为空,则抛出异常NoSuchElement;
(6) public E poll()
八、 遍历
类似于ArrayList