LinkedList源码分析
来源:互联网 发布:索尼挂起网络解决办法 编辑:程序博客网 时间:2024/06/07 02:06
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
源码版本为JDK1.7.0_75.
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;
其中,Node类为LinkedList内部静态类
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; }
// Positional Access Operation 位置访问操作
根据下表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; } }
// Search Operations 搜索操作
indexOf和lastIndexOf也是遍历链表查找。
// Queue Operations 队列操作
<strong> </strong> /*** 返回队首元素,但不删除队首,若不存在,返回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); }
// Deque operations 双端队列操作
/*** 将特定元素插入到队首 * 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; }
clone方法首先调用superClone方法(该方法调用父类clone方法)得到链表,然后遍历原始链表将节点添加新链表中。该方法属于浅拷贝。
@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; }
参考:
http://www.cnblogs.com/ITtangtang/p/3948610.html
- LinkedList 源码分析
- LinkedList源码分析
- ArrayList LinkedList 源码分析
- ArrayList,LinkedList源码分析
- 源码分析之LinkedList
- LinkedList源码分析
- LinkedList源码分析
- Java LinkedLIst 源码分析
- LinkedList源码分析
- 【java源码分析】-LinkedList
- LinkedList源码分析
- LinkedList源码分析
- Java LinkedList 源码分析
- LinkedList源码分析(unfinished)
- LinkedList的源码分析
- LinkedList源码分析
- LinkedList源码分析
- 源码分析—LinkedList
- hdu 2612 简单搜索
- Swift UI搭建新得(-) -- 驾驭 StoryBoard
- BZOJ3669: [Noi2014]魔法森林
- Go for Visual Studio Code
- JAVA多线程-线程间通信(四)-join的使用
- LinkedList源码分析
- scrapy 爬网站 显示 Filtered offsite request to 错误.
- Ubutu+Apache+Mono 实现.net开发的网站跨平台移植
- 【bzoj2599】: [IOI2011]Race
- Git从零教你入门(4):Git服务之 gogs部署安装
- hdoj2030 汉字统计
- 【POJ】1258 - Agri-Net(克鲁斯塔尔)(水)
- STM32的bootloader IAP编程(转载总结)
- 改变系统默认的语言,back改为中文,delete改为中文