LinkedList Class

前言:

    永远没有准备好的时候,不过这样也挺好的,加油吧

    看了源码,以后技术类博客立志要写高质量的,否则不写,起码不发出来

    源码不难,静下心、很重要;纯属写给自己看、纯属写给自己看、纯属写给自己看!!!

 

总结
(01) LinkedList 实际上是通过双向链表去实现的
        它包含一个非常重要的内部类:Entry

       Entry是双向链表节点所对应的数据结构,它包括的属性有:当前节点所包含的值上一个节点下一个节点
(02) 从LinkedList的实现方式中可以发现,它不存在LinkedList容量不足的问题。
(03) LinkedList的克隆函数,即是将全部元素克隆到一个新的LinkedList对象中。
(04) LinkedList实现java.io.Serializable。当写入到输出流时,先写入“容量”,再依次写入“每一个节点保护的值”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。
(05) 由于LinkedList实现了Deque,而Deque接口定义了在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(null 或 false,具体取决于操作)。

 

参考:

https://www.cnblogs.com/acme6/p/7543895.html

http://www.cnblogs.com/skywang12345/p/3308807.html

https://baike.baidu.com/item/AbstractSequentialList/10627023?fr=aladdin

LinkedList:位于package java.util;线程不安全、容许元素为null,底层是链表

   随机访问时:据index判断前半段还是后半段,决定查询顺序

   增删只需移动指针 :时间效率高,不需要批量扩容、预留空间,空间效率较ArrayList高

盗图一张

关键词:

not synchronized ;

iterators :fail-fast;

implementation of list and Deque;
Collections.synchronizedList(new LinkedList(...));  

Doubly-linked list implementation of the {@code List} and {@code Deque}interfaces. Implements all optional list operations, and permits all elements (including {@code null}).

All of the operations perform as could be expected for a doubly-linked list.  Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index.

If no such object exists, the list should be "wrapped" using the {@link Collections#synchronizedList Collections.synchronizedList} method.  This is best done at creation time, to prevent accidental unsynchronized access to the list:<pre> List list = Collections.synchronizedList(new LinkedList(...));

The iterators returned by this class's {@code iterator} and {@code listIterator} methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the Iterator's own {@code remove} or {@code add} methods, the iterator will throw a {@link ConcurrentModificationException}.  Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather tha risking arbitrary, non-deterministic behavior at an undetermined
time in the future.
AbstractSequentialList:
提供一个基本的List接口实现,为实现序列访问的数据储存结构的提供了所需要的最小化的接口实现。
对于支持随机访问数据的List比如数组,应优先使用AbstractList:其主要方法都是通过迭代器实现的
This class provides a skeletal implementation of the List interface
to minimize the effort required to implement this interface backed 
by a "sequential access" data store (such as a linked list). 
For random access data (such as an array), AbstractList should be used in preference to this class.
具体回来看LinkedList:
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable{  
    transient int size = 0;//集合元素数量;  transient:不参与序列化过程
    transient Node<E> first;//链表头节点
    transient Node<E> last;//链表尾节点
    public LinkedList() {}
    /*将集合c所有元素插入链表中,NullPointerException*/
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }
    /**
     * Links e as first element 
       新建一个节点,并将其赋给第一个节点,
        如果第一个节点为空则该list没有节点,最后一个节点也赋值为新节点
        否则第一个节点的前置指针指向新节点,使得新节点成为第一个元素
       list的size
     */
    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;//第一个元素为null则最后一个节点也赋值为newNode,只要一个节点
        else
            f.prev = newNode;
        size++;
        modCount++;// protected transient int modCount = 0;
    }
    /**
     * Links e as last element.插入最后一个元素,同linkFirst
     */
    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++;//list在结构上修改的次数
    }
	
     /**
     * Inserts element e before non-null Node succ.
	 * e待插入节点的数据
	 * succ在谁前插入
     */
    void linkBefore(E e, Node<E> succ) {
        final Node<E> pred = succ.prev;//succ的前置节点
        final Node<E> newNode = new Node<>(pred, e, succ);//前后位置确定
        succ.prev = newNode;//succ的前置节点置为newNode
        if (pred == null)//succ为首节点
            first = newNode;
        else
            pred.next = newNode;//前置节点的后置指针指向新节点
        size++;
        modCount++;
    }
	
	/**
     * Unlinks non-null first node f.
		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; //置null ,取消引用
        f.next = null; // help GC
        first = next; //下一节点置为首节点
        if (next == null)
            last = null;//下一节点为null,list原来只有首节点
        else
            next.prev = null;//下一节点前节点置空
        size--;
        modCount++;
        return element;
    }
	/**
	* 过于简单
     * Unlinks non-null last node l.思想同unlinkFirst
     */
    private E unlinkLast(Node<E> l) {……}
	 
	 /**
     * 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;//清空自身,便于GC
        size--;
        modCount++;
        return element;
    }
	
	 /**
	 * 过于简单
     * Returns the first element in this list.
     *
     * @return the first element in this list
     * @throws NoSuchElementException if this list is empty
     */
    public E getFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }
	/*同getFirst*/
	 public E getLast() {……}
	 
	/**
     * Removes and returns the first element from this list.
     *
     * @return the first element from this list
     * @throws NoSuchElementException if this list is empty
     */
    public E removeFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
    }
	public E removeLast() {……}
	/** 过于简单*/
	public void addFirst(E e) {
        linkFirst(e);
    }
	/** 过于简单*/
	public void addLast(E e) {
        linkLast(e);
    }
	/** 过于简单*/
	 public boolean contains(Object o) {
        return indexOf(o) != -1;
    }
	/** 过于简单*/
	public int size() {
        return size;
    }
	/** 过于简单*/
	public boolean add(E e) {
        linkLast(e);
        return true;
    }
	
	public boolean remove(Object o) {
        if (o == null) {
			//o为null,第一个开始遍历,是空的为什么还要遍历呐?
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
			//o!=null
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);//移除指定元素节点
                    return true;
                }
            }
        }
        return false;
    }
	public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }
	public boolean addAll(int index, Collection<? extends E> c) {
        checkPositionIndex(index);//检查索引有无超纲

        Object[] a = c.toArray();//转数组
        int numNew = a.length;
        if (numNew == 0)
            return false;

        Node<E> pred, succ;
        if (index == size) {//尾部插入
            succ = null;
            pred = last;//当前尾节点置为插入节点的前置节点
        } else {
            succ = node(index);//在指针帮助下据索引位置找到对应的节点
            pred = succ.prev;//当前节点的前置指针指向空节点pred
        }
		//要插入的数组
        for (Object o : a) {
            @SuppressWarnings("unchecked") E e = (E) o;
			//带有前置节点的待插入节点
            Node<E> newNode = new Node<>(pred, e, null);
            if (pred == null)//前置节点为空
                first = newNode;//当前置为首节点
            else
                pred.next = newNode;//当前节点与上面找到的前置节点建立联系
            pred = newNode;//当前节点置为前置节点,依次往后面插入
        }
		//根据索引没有找到节点
        if (succ == null) {
            last = pred;//尾节点为前置节点
        } else {
            pred.next = succ;//已经完成插入,建立插入节点与找到节点的联系
            succ.prev = pred;
        }

        size += numNew;
        modCount++;
        return true;
    }
	
	/*过于简单*/
	public void clear() {
        // Clearing all of the links between nodes is "unnecessary", but:
        // - helps a generational GC if the discarded nodes inhabit
        //   more than one generation
        // - is sure to free memory even if there is a reachable Iterator
        for (Node<E> x = first; x != null; ) {
            Node<E> next = x.next;
            x.item = null;
            x.next = null;
            x.prev = null;
            x = next;
        }
        first = last = null;
        size = 0;
        modCount++;
    }
	
	// Positional Access Operations———————————————————————————————
	public E get(int index) {
        checkElementIndex(index);//索引是否超纲,异常
        return node(index).item;
    }
	 public E set(int index, E element) {
        checkElementIndex(index);
        Node<E> x = node(index);//在指针帮助下据索引位置找到对应的节点
        E oldVal = x.item;//原来的值变成旧值,用于返回
        x.item = element;
        return oldVal;
    }
	public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)//尾部插入
            linkLast(element);
        else
            linkBefore(element, node(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;
        }
    }
	//根据o找到对应的索引
	public int indexOf(Object o) {
        int index = 0;
        if (o == null) {
			//从第一个开始 
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;//o==null item==null return
                index++;
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;//if this list does not contain the element
    }
	
	// Search Operations———————————————————————————————————————————
	/**
     * Returns the index of the last occurrence of the specified element
     * in this list, or -1 if this list does not contain the element
     */
	 public int lastIndexOf(Object o) {
        int index = size;
        if (o == null) {
			//倒序 从last开始
            for (Node<E> x = last; x != null; x = x.prev) {
                index--;
                if (x.item == null)
                    return index;
            }
        } else {
            for (Node<E> x = last; x != null; x = x.prev) {
                index--;
                if (o.equals(x.item))
                    return index;
            }
        }
        return -1;
    }
	
	// Queue operations.——————————————————————————————————————————
	/*Retrieves, but does not remove, the head (first element) of this list.*/
	 public E peek() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
    }
	 public E element() {
        return getFirst();
    }
	/*Retrieves and removes the head (first element) of this list.*/
	public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }
	 public E remove() {
        return removeFirst();
    }
	/*Adds the specified element as the tail (last element) of this list*/
	 public boolean offer(E e) {
        return add(e);
    }
	
	// Deque operations since 1.6-------------------------------------------
	public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }
	public boolean offerLast(E e) {
        addLast(e);
        return true;
    }
	//peekLast  pollFirst   pollLast   
	public E peekFirst() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
     }
	  public void push(E e) {
        addFirst(e);
    }
	public E pop() {
        return removeFirst();
    }
	 public boolean removeFirstOccurrence(Object o) {
        return remove(o);
    }
	/**
	* Removes the last occurrence of the specified element
	*/
	 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;
    }
	
	
	public ListIterator<E> listIterator(int index) {
        checkPositionIndex(index);
        return new ListItr(index);
    }
	
	//内部类
	 private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned;//最后返回节点
        private Node<E> next;//当前节点
        private int nextIndex;//节点索引
        private int expectedModCount = modCount;//修改次数

        ListItr(int index) {
            // assert isPositionIndex(index);
            next = (index == size) ? null : node(index);
            nextIndex = index;
        }

        public boolean hasNext() {
            return nextIndex < size;
        }

        public E next() {
            checkForComodification();//检索修改次数
            if (!hasNext())
                throw new NoSuchElementException();
			
            lastReturned = next;
            next = next.next;
            nextIndex++;
            return lastReturned.item;
        }

        public boolean hasPrevious() {
            return nextIndex > 0;
        }

        public E previous() {
            checkForComodification();
            if (!hasPrevious())
                throw new NoSuchElementException();

            lastReturned = next = (next == null) ? last : next.prev;
            nextIndex--;
            return lastReturned.item;
        }

        public int nextIndex() {
            return nextIndex;
        }

        public int previousIndex() {
            return nextIndex - 1;
        }

        public void remove() {
            checkForComodification();
            if (lastReturned == null)
                throw new IllegalStateException();

            Node<E> lastNext = lastReturned.next;
            unlink(lastReturned);
            if (next == lastReturned)
                next = lastNext;
            else
                nextIndex--;
            lastReturned = null;
            expectedModCount++;
        }

        public void set(E e) {
            if (lastReturned == null)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.item = e;
        }

        public void add(E e) {
            checkForComodification();
            lastReturned = null;
            if (next == null)
                linkLast(e);
            else
                linkBefore(e, next);
            nextIndex++;
            expectedModCount++;
        }
		
        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);//判空
            while (modCount == expectedModCount && nextIndex < size) {
                action.accept(next.item);
                lastReturned = next;
                next = next.next;
                nextIndex++;
            }
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

    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;
        }
    }
	 private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned;
        private Node<E> next;
        private int nextIndex;
        private int expectedModCount = modCount;

        ListItr(int index) {
            // assert isPositionIndex(index);
            next = (index == size) ? null : node(index);
            nextIndex = index;
        }

        public boolean hasNext() {
            return nextIndex < size;
        }

        public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();

            lastReturned = next;
            next = next.next;
            nextIndex++;
            return lastReturned.item;
        }

        public boolean hasPrevious() {
            return nextIndex > 0;
        }

        public E previous() {
            checkForComodification();
            if (!hasPrevious())
                throw new NoSuchElementException();

            lastReturned = next = (next == null) ? last : next.prev;
            nextIndex--;
            return lastReturned.item;
        }

        public int nextIndex() {
            return nextIndex;
        }

        public int previousIndex() {
            return nextIndex - 1;
        }

        public void remove() {
            checkForComodification();
            if (lastReturned == null)
                throw new IllegalStateException();

            Node<E> lastNext = lastReturned.next;
            unlink(lastReturned);
            if (next == lastReturned)
                next = lastNext;
            else
                nextIndex--;
            lastReturned = null;
            expectedModCount++;
        }

        public void set(E e) {
            if (lastReturned == null)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.item = e;
        }

        public void add(E e) {
            checkForComodification();
            lastReturned = null;
            if (next == null)
                linkLast(e);
            else
                linkBefore(e, next);
            nextIndex++;
            expectedModCount++;
        }

        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            while (modCount == expectedModCount && nextIndex < size) {
                action.accept(next.item);
                lastReturned = next;
                next = next.next;
                nextIndex++;
            }
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

    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;
        }
    }
	public Iterator<E> descendingIterator() {
        return new DescendingIterator();
    }
	private class DescendingIterator implements Iterator<E> {
        private final ListItr itr = new ListItr(size());
        public boolean hasNext() {
            return itr.hasPrevious();
        }
        public E next() {
            return itr.previous();
        }
        public void remove() {
            itr.remove();
        }
		@SuppressWarnings("unchecked")
		private LinkedList<E> superClone() {
        try {
            return (LinkedList<E>) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e);
        }
		}
    }
	/*shallow copy */
	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;
    }
	 public Object[] toArray() {
        Object[] result = new Object[size];
        int i = 0;
        for (Node<E> x = first; x != null; x = x.next)
            result[i++] = x.item;
        return result;
    }
	@SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
		//数组a不能容纳LinkedList中全部元素
        if (a.length < size)
			//newArray(componentType, length);
            a = (T[])java.lang.reflect.Array.newInstance(
                                a.getClass().getComponentType(), size);
        int i = 0;
        Object[] result = a;
        for (Node<E> x = first; x != null; x = x.next)
            result[i++] = x.item;
		
        if (a.length > size)
            a[size] = null;

        return a;
    }
	
	private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        // Write out any hidden serialization magic
        s.defaultWriteObject();//SerialCallbackContext

        // Write out size
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (Node<E> x = first; x != null; x = x.next)
            s.writeObject(x.item);
    }
	@SuppressWarnings("unchecked")
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        // Read in any hidden serialization magic
        s.defaultReadObject();

        // Read in size
        int size = s.readInt();

        // Read in all elements in the proper order.
        for (int i = 0; i < size; i++)
            linkLast((E)s.readObject());
    }
	@Override
    public Spliterator<E> spliterator() {
        return new LLSpliterator<E>(this, -1, 0);
    }
	/** A customized variant of Spliterators.IteratorSpliterator */
    static final class LLSpliterator<E> implements Spliterator<E> {
        static final int BATCH_UNIT = 1 << 10;  // 1*2^10 batch array size increment
        static final int MAX_BATCH = 1 << 25;  //1*2^25 max batch array size;
        final LinkedList<E> list; // null OK unless traversed
        Node<E> current;      // current node; null until initialized
        int est;              // size estimate; -1 until first needed
        int expectedModCount; // initialized when est set
        int batch;            // batch size for splits

        LLSpliterator(LinkedList<E> list, int est, int expectedModCount) {
            this.list = list;
            this.est = est;
            this.expectedModCount = expectedModCount;
        }

        final int getEst() {
            int s; // force initialization
            final LinkedList<E> lst;
            if ((s = est) < 0) {
                if ((lst = list) == null)
                    s = est = 0;//没有元素
                else {
                    expectedModCount = lst.modCount;
                    current = lst.first;
                    s = est = lst.size;
                }
            }
            return s;
        }

        public long estimateSize() { return (long) getEst(); }

        public Spliterator<E> trySplit() {
            Node<E> p;
            int s = getEst();
            if (s > 1 && (p = current) != null) {
                int n = batch + BATCH_UNIT;
                if (n > s)
                    n = s;
                if (n > MAX_BATCH)
                    n = MAX_BATCH;
                Object[] a = new Object[n];
                int j = 0;
                do { a[j++] = p.item; } while ((p = p.next) != null && j < n);
                current = p;
                batch = j;
                est = s - j;
                return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);
            }
            return null;
        }

        public void forEachRemaining(Consumer<? super E> action) {
            Node<E> p; int n;
            if (action == null) throw new NullPointerException();
            if ((n = getEst()) > 0 && (p = current) != null) {
                current = null;
                est = 0;
                do {
                    E e = p.item;
                    p = p.next;
                    action.accept(e);
                } while (p != null && --n > 0);
            }
            if (list.modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

        public boolean tryAdvance(Consumer<? super E> action) {
            Node<E> p;
            if (action == null) throw new NullPointerException();
            if (getEst() > 0 && (p = current) != null) {
                --est;
                E e = p.item;
                current = p.next;
                action.accept(e);
                if (list.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                return true;
            }
            return false;
        }

        public int characteristics() {
            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
        }
    }

}
	

啊,终于等到你、ending……

主要是自己看的,也证明自己看过源码了,代码中作者很细心,看注释、命名对于这个类的理解很有帮助,嗯,新的开始,加油

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值