List之LinkedList源码分析
2016-02-19 16:14
399 查看
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable |
LinkedList继承了类AbstractSequentialList的双向链表,可以被当作堆栈、队列或双端队列进行操作。
LinkedList实现了List接口,可被当作队列操作;实现了Deque接口,可被当作双端队列操作;实现了Cloneable接口,说明可被克隆;实现了java.io.Serializable接口,说明它支持序列化。LinkedList是非同步的。
在网上找到的LinkedList源码分析好像大部分都是JDK1.6,其LinkedList使用的是循环双向链表,只有一个header,header结点不保存数据,而1.7版本改成非循环双向链表,分别使用first和last指向队首、队尾,这样对于在队首、队尾添加或删除等操作都只要O(1)的时间。
成员变量
transient int size = 0; /** * 指向头部的指针 * Pointer to first node. * Invariant: (first == null && last == null) || * (first.prev == null && first.item != null) */ transient Node<E> first; /** * 指向尾部的指针 * Pointer to last node. * Invariant: (first == null && last == null) || * (last.next == null && last.item != null) */ 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; } } |
一个是构造空队列;另一个是将Collection集合数据添加到队列中。
/** * Constructs an empty list. */ public LinkedList() { } /** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's * iterator. * * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ public LinkedList(Collection<? extends E> c) { this(); addAll(c); } |
linkFirst、linkLast、linkBefore、unLinkBefore、unLinkLast、unLink这些方法主要是为add、remove等public方法服务。
/** * 将元素e添加到头部,首先创建节点保存元素e,然后将该节点的next指向first,若first不为空,则将first的prev指向该节点;若first为空,则修改last指向该节点。 * Links e as first element. */ private void linkFirst(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++; } /** * 将元素e插入到尾部。首先创建节点保存元素e,若last不为空,则将该节点的prev指向last,否则修改first指向该节点。 * 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++; } /** * 将元素e插入到非空节点succ之前。 * Inserts element e before non-null Node succ. */ void linkBefore(E e, Node<E> succ) { // assert succ != null; final Node<E> pred = succ.prev; final Node<E> newNode = new Node<>(pred, e, succ); succ.prev = newNode; if (pred == null) first = newNode; else pred.next = newNode; size++; modCount++; } /** * 删除非空头节点f。修改first,注意要将头节点的成员变量都设置为null,使得该节点被GC回收 * Unlinks non-null first node f. */ private E unlinkFirst(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; } /** * 删除最后一个非空节点。修改last。 * Unlinks non-null last node l. */ private E unlinkLast(Node<E> l) { // assert l == last && l != null; final E element = l.item; final Node<E> prev = l.prev; l.item = null; l.prev = null; // help GC last = prev; if (prev == null) first = null; else prev.next = null; size--; modCount++; return element; } /** * 删除链表中非空节点x。 * Unlinks non-null node x. */ 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; size--; modCount++; return element; } |
根据下表index查找并返回结点,方法get、set、add、remove主要利用该方法实现。它根据index是否大于size/2来确定是从头遍历还是从尾遍历。
/** * Returns the (non-null) Node at the specified element index. */ Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } |
indexOf和lastIndexOf也是遍历链表查找。
// Queue Operations 队列操作
/** * 返回队首元素,但不删除队首,若不存在,返回null * Retrieves, but does not remove, the head (first element) of this list. * * @return the head of this list, or {@code null} if this list is empty * @since 1.5 */ public E peek() { final Node<E> f = first; return (f == null) ? null : f.item; } /** * 返回队首元素,但不删除,若不存在,抛出异常 * Retrieves, but does not remove, the head (first element) of this list. * * @return the head of this list * @throws NoSuchElementException if this list is empty * @since 1.5 */ public E element() { return getFirst(); } /** * 返回并删除队首元素,若为空,返回null * Retrieves and removes the head (first element) of this list. * * @return the head of this list, or {@code null} if this list is empty * @since 1.5 */ public E poll() { final Node<E> f = first; return (f == null) ? null : unlinkFirst(f); } /** * 返回并删除队首元素,若为空,抛出异常 * Retrieves and removes the head (first element) of this list. * * @return the head of this list * @throws NoSuchElementException if this list is empty * @since 1.5 */ public E remove() { return removeFirst(); } /** * 将特定元素添加到队尾 * Adds the specified element as the tail (last element) of this list. * * @param e the element to add * @return {@code true} (as specified by {@link Queue#offer}) * @since 1.5 */ public boolean offer(E e) { return add(e); } |
/** * 将特定元素插入到队首 * Inserts the specified element at the front of this list. * * @param e the element to insert * @return {@code true} (as specified by {@link Deque#offerFirst}) * @since 1.6 */ public boolean offerFirst(E e) { addFirst(e); return true; } /** * 将特定元素插入到队尾 * Inserts the specified element at the end of this list. * * @param e the element to insert * @return {@code true} (as specified by {@link Deque#offerLast}) * @since 1.6 */ public boolean offerLast(E e) { addLast(e); return true; } /** * 返回但不删除队列第一个元素,若为空,则返回null * Retrieves, but does not remove, the first element of this list, * or returns {@code null} if this list is empty. * * @return the first element of this list, or {@code null} * if this list is empty * @since 1.6 */ public E peekFirst() { final Node<E> f = first; return (f == null) ? null : f.item; } /** * 返回但不删除队列最后一个元素,若为空,则返回null * Retrieves, but does not remove, the last element of this list, * or returns {@code null} if this list is empty. * * @return the last element of this list, or {@code null} * if this list is empty * @since 1.6 */ public E peekLast() { final Node<E> l = last; return (l == null) ? null : l.item; } /** * 返回并删除队列第一个元素,若为空,则返回null * Retrieves and removes the first element of this list, * or returns {@code null} if this list is empty. * * @return the first element of this list, or {@code null} if * this list is empty * @since 1.6 */ public E pollFirst() { final Node<E> f = first; return (f == null) ? null : unlinkFirst(f); } /** * 返回并删除队列最后一个元素,若为空,则返回null * Retrieves and removes the last element of this list, * or returns {@code null} if this list is empty. * * @return the last element of this list, or {@code null} if * this list is empty * @since 1.6 */ public E pollLast() { final Node<E> l = last; return (l == null) ? null : unlinkLast(l); } /** * Pushes an element onto the stack represented by this list. In other * words, inserts the element at the front of this list. * * <p>This method is equivalent to {@link #addFirst}. * * @param e the element to push * @since 1.6 */ public void push(E e) { addFirst(e); } /** * Pops an element from the stack represented by this list. In other * words, removes and returns the first element of this list. * * <p>This method is equivalent to {@link #removeFirst()}. * * @return the element at the front of this list (which is the top * of the stack represented by this list) * @throws NoSuchElementException if this list is empty * @since 1.6 */ public E pop() { return removeFirst(); } /** * Removes the first occurrence of the specified element in this * list (when traversing the list from head to tail). If the list * does not contain the element, it is unchanged. * * @param o element to be removed from this list, if present * @return {@code true} if the list contained the specified element * @since 1.6 */ public boolean removeFirstOccurrence(Object o) { return remove(o); } /** * Removes the last occurrence of the specified element in this * list (when traversing the list from head to tail). If the list * does not contain the element, it is unchanged. * * @param o element to be removed from this list, if present * @return {@code true} if the list contained the specified element * @since 1.6 */ public boolean removeLastOccurrence(Object o) { if (o == null) { for (Node<E> x = last; x != null; x = x.prev) { if (x.item == null) { unlink(x); return true; } } } else { for (Node<E> x = last; x != null; x = x.prev) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; } |
@SuppressWarnings("unchecked") private LinkedList<E> superClone() { try { return (LinkedList<E>) super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } } /** * Returns a shallow copy of this {@code LinkedList}. (The elements * themselves are not cloned.) * * @return a shallow copy of this {@code LinkedList} instance */ public Object clone() { LinkedList<E> clone = superClone(); // Put clone into "virgin" state clone.first = clone.last = null; clone.size = 0; clone.modCount = 0; // Initialize clone with our elements for (Node<E> x = first; x != null; x = x.next) clone.add(x.item); return clone; } |
/article/5049987.html
相关文章推荐
- 通过 Redis 实现 RPC 远程方法调用(支持多种编程语
- php非代码级缓存技术(服务器)介绍
- opencv contrib-master ximgproc module doc note
- java二次开发微信公众号授权
- QT笔记:数据库总结(一)
- TCP/IP三次握手与四次挥手学习笔记
- php代码级别缓存技术介绍
- utilities(C/C++)(二)
- ProjectOne(02) - 创建一个package.json文件
- 深入理解子类和父类之间关系
- 桥接模式——多对多的连接
- HDU 1284 钱币兑换问题 (数学)
- 在 Visual Studio 等编辑器/IDE中自动切换输入法,不需要手动的有没有?
- linux下的第一个C程序及其编译方法
- linux软链接和硬链接的区别
- javascript的事件冒泡和事件捕获
- Git -- 标签管理
- OpenCV——PS滤镜算法之 球面化 (凹陷效果)
- OpenCV——PS滤镜算法之Spherize 球面化(凸出效果)
- Win10系统怎么卸载IE浏览器?Win10系统卸载IE浏览器教程