美文网首页
java基础—浅析LinkedList源码

java基础—浅析LinkedList源码

作者: 锋Plus | 来源:发表于2017-10-18 20:11 被阅读8次

    LinkedList简介

    LinkedList是基于双向链表(从源码中可以很容易看出)实现的,除了可以当作链表来操作外,它还可以当作栈,队列和双端队列来使用。

    LinkedList同样是非线程安全的,只在单线程下适合使用。

    LinkedList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了Cloneable接口,能被克隆。

    LinkedList的存储单元为一个名为Node的内部类,包含prev指针,next指针,和item元素,实现为双向链表

    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;
        }
    }
    

    如果对双向链表这个数据结构很熟悉的话,学习 LinkedList 就没什么难度了。下面是双向链表的结构:


    双向链表的结构

    双向链表每个结点除了数据域之外,还有一个前指针和后指针,分别指向前驱结点和后继结点(如果有前驱/后继的话)。另外,双向链表还有一个first指针,指向头节点,和last指针,指向尾节点。

    LinkedList源码解析

    关于AbstractSequentialList参考文章:http://blog.csdn.net/u011240877/article/details/52854681

    
    package java.util;
    
    import java.util.function.Consumer;
    
    public class LinkedList<E>
        extends AbstractSequentialList<E>
        implements List<E>, Deque<E>, Cloneable, java.io.Serializable
    {
        // 链表的节点个数
        transient int size = 0;
    
        // 指向头节点的指针
        transient Node<E> first;
        // 指向尾节点的指针
        transient Node<E> last;
    
        public LinkedList() {
        }
    
        // 该构造函数,先创建一个空的LinkedList,然后把所有元素加进去
        public LinkedList(Collection<? extends E> c) {
            this();
            addAll(c);
        }
    
        // 把一个元素添加都第一个位置
        // 注意:以下link、unlink开头的函数都为私有函数
        private void linkFirst(E e) {
            final Node<E> f = first;
            //当前节点的前驱指向null,后继指针原来的头节点
            final Node<E> newNode = new Node<>(null, e, f);
            //头指针指向新的头节点
            first = newNode;
             //如果原来没有头节点,则更新尾指针,否则更新原来节点的前驱指针
            if (f == null)
                last = newNode;
            else
                f.prev = newNode;
            size++;
            modCount++;
        }
    
        // 把一个元素添加到最后一个位置
        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++;
        }
    
        // 在某个元素前添加元素
        void linkBefore(E e, Node<E> succ) {
            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++;
        }
    
        // 删除第一个元素,注意传入的需为第一个元素,不然链表会出现违背本意情况
        private E unlinkFirst(Node<E> f) {
            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;
        }
    
        // 删除某个元素
        private E unlinkLast(Node<E> l) {
            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;
        }
    
        // 删除某个元素
        E unlink(Node<E> x) {
            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;
        }
    
        // 获取第一个元素
        public E getFirst() {
            final Node<E> f = first;
            if (f == null)
                throw new NoSuchElementException();
            return f.item;
        }
    
        // 获取最后一个元素
        public E getLast() {
            final Node<E> l = last;
            if (l == null)
                throw new NoSuchElementException();
            return l.item;
        }
    
        // 删除表头元素
        public E removeFirst() {
            final Node<E> f = first;
            if (f == null)
                throw new NoSuchElementException();
            return unlinkFirst(f);
        }
    
        // 删除表尾元素
        public E removeLast() {
            final Node<E> l = last;
            if (l == null)
                throw new NoSuchElementException();
            return unlinkLast(l);
        }
    
        // 插入新的表头节点
        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) {
                for (Node<E> x = first; x != null; x = x.next) {
                    if (x.item == null) {
                        unlink(x);
                        return true;
                    }
                }
            } else {
                for (Node<E> x = first; x != null; x = x.next) {
                    if (o.equals(x.item)) {
                        unlink(x);
                        return true;
                    }
                }
            }
            return false;
        }
        
        // 将“集合(c)”添加到LinkedList中。    
        // 实际上,是从双向链表的末尾开始,将“集合(c)”添加到双向链表中。 
        public boolean addAll(Collection<? extends E> c) {
            return addAll(size, c);
        }
    
        // 从双向链表的index开始,将“集合(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;
            }
    
            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() {    
            // 从表头开始,逐个向后遍历;对遍历到的节点执行一下操作:    
            // (01) 设置前一个节点为null     
            // (02) 设置当前节点的内容为null     
            // (03) 设置后一个节点为“新的当前节点”    
           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++;  
        }  
    
        // 以下为位置相关操作
        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));
        }
    
        public E remove(int index) {
            checkElementIndex(index);
            return unlink(node(index));
        }
    
        // 判断现有的链表范围,即 <= 0 < n
        private boolean isElementIndex(int index) {
            return index >= 0 && index < size;
        }
    
        // 判断是否为正确位置,如对于迭代器,或者添加操作,即 <= 0 <= n
        private boolean isPositionIndex(int index) {
            return index >= 0 && index <= size;
        }
    
        private String outOfBoundsMsg(int index) {
            return "Index: "+index+", Size: "+size;
        }
    
        private void checkElementIndex(int index) {
            if (!isElementIndex(index))
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    
        private void checkPositionIndex(int index) {
            if (!isPositionIndex(index))
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    
        // 该方法会判断元素离头部比较近,还是尾巴比较近,然后开始遍历
        Node<E> node(int 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;
            }
        }
    
        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;
                    index++;
                }
            } else {
                for (Node<E> x = first; x != null; x = x.next) {
                    if (o.equals(x.item))
                        return index;
                    index++;
                }
            }
            return -1;
        }
    
        public int lastIndexOf(Object o) {
            int index = size;
            if (o == null) {
                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;
        }
    
        // 以下为队列操作
    
        // 获取表头节点的值,表头为空返回null
        public E peek() {
            final Node<E> f = first;
            return (f == null) ? null : f.item;
        }
    
        // 获取表头节点的值,表头为空抛出异常
        public E element() {
            return getFirst();
        }
    
        // 获取表头节点的值,并删除表头节点,表头为空返回null
        public E poll() {
            final Node<E> f = first;
            return (f == null) ? null : unlinkFirst(f);
        }
    
        public E remove() {
            return removeFirst();
        }
    
        public boolean offer(E e) {
            return add(e);
        }
    
        // 以下为双向队列操作
        public boolean offerFirst(E e) {
            addFirst(e);
            return true;
        }
    
        public boolean offerLast(E e) {
            addLast(e);
            return true;
        }
    
        public E peekFirst() {
            final Node<E> f = first;
            return (f == null) ? null : f.item;
         }
    
        public E peekLast() {
            final Node<E> l = last;
            return (l == null) ? null : l.item;
        }
    
        public E pollFirst() {
            final Node<E> f = first;
            return (f == null) ? null : unlinkFirst(f);
        }
    
        public E pollLast() {
            final Node<E> l = last;
            return (l == null) ? null : unlinkLast(l);
        }
    
        // 添加元素到表头
        public void push(E e) {
            addFirst(e);
        }
    
        // 删除表头元素
        public E pop() {
            return removeFirst();
        }
    
        public boolean removeFirstOccurrence(Object o) {
            return remove(o);
        }
    
        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;
        }
        
            // 返回“index到末尾的全部节点”对应的ListIterator对象(List迭代器)    
        public ListIterator<E> listIterator(int index) {    
            return new ListItr(index);    
        }    
       
        // List迭代器    
        private class ListItr implements ListIterator<E> {    
            // 上一次返回的节点    
            private Node<E> lastReturned = null;    
            // 下一个节点    
            private Node<E> next;    
            // 下一个节点对应的索引值    
            private int nextIndex;    
            // 期望的改变计数。用来实现fail-fast机制。    
            private int expectedModCount = modCount;    
       
            // 构造函数。    
            // 从index位置开始进行迭代    
            ListItr(int index) {    
                next = (index == size) ? null : node(index);
                nextIndex = index;
            }    
       
            // 是否存在下一个元素    
            public boolean hasNext() {    
                // 通过元素索引是否小于“双向链表大小”来判断是否达到最后。    
                return nextIndex < size;    
            }    
       
            // 获取下一个元素    
            public E next() {    
                checkForComodification();    
                if (nextIndex == size)    
                    throw new NoSuchElementException();    
       
                lastReturned = next;    
                // next指向链表的下一个元素    
                next = next.next;    
                nextIndex++;    
                return lastReturned.element;    
            }    
       
            // 是否存在上一个元素    
            public boolean hasPrevious() {    
                // 通过元素索引是否等于0,来判断是否达到开头。    
                return nextIndex > 0;    
            }    
       
            // 获取上一个元素    
            public E previous() {    
                if (nextIndex == 0)    
                throw new NoSuchElementException();    
       
                // next指向链表的上一个元素    
                lastReturned = next = next.previous;    
                nextIndex--;    
                checkForComodification();    
                return lastReturned.element;    
            }    
       
            // 获取下一个元素的索引    
            public int nextIndex() {    
                return nextIndex;    
            }    
       
            // 获取上一个元素的索引    
            public int previousIndex() {    
                return nextIndex-1;    
            }    
       
            // 删除当前元素。    
            // 删除双向链表中的当前节点    
            public void remove() {    
                checkForComodification();    
                Node<E> lastNext = lastReturned.next;    
                try {    
                    LinkedList.this.remove(lastReturned);    
                } catch (NoSuchElementException e) {    
                    throw new IllegalStateException();    
                }    
                if (next==lastReturned)    
                    next = lastNext;    
                else   
                    nextIndex--;    
                lastReturned = null;    
                expectedModCount++;    
            }    
       
            // 设置当前节点为e    
            public void set(E e) {    
                if (lastReturned == null)    
                    throw new IllegalStateException();    
                checkForComodification();    
                lastReturned.element = e;    
            }    
       
            // 将e添加到当前节点的前面    
            public void add(E e) {    
                checkForComodification();
                lastReturned = null;
                if (next == null)
                    linkLast(e);
                else
                    linkBefore(e, next);
                nextIndex++;
                expectedModCount++;   
            }    
       
            // 判断 “modCount和expectedModCount是否相等”,依次来实现fail-fast机制。    
            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 {    
            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);
            }
        }
    
        // 浅拷贝
        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) {
            if (a.length < size)
                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 static final long serialVersionUID = 876323262645176354L;
    
        // java.io.Serializable的写入函数    
        // 将LinkedList的“容量,所有的元素值”都写入到输出流中 
        private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
            // Write out any hidden serialization magic
            s.defaultWriteObject();
    
            // 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);
        }
    
        // java.io.Serializable的读取函数:根据写入方式反向读出    
        // 先将LinkedList的“容量”读出,然后将“所有的元素值”读出 
        @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());
        }
    }
    

    几点总结

    1. LinkedList有两个构造参数,一个为无參构造,只是新建一个空对象,第二个为有参构造,新建一个空对象,然后把所有元素添加进去。

    2. 在查找和删除某元素时,源码中都划分为该元素为null和不为null两种情况来处理,LinkedList中允许元素为null。

    3. LinkedList是基于链表实现的,因此不存在容量不足的问题,所以这里没有扩容的方法。

    4. 注意源码中的Node node(int index)方法。该方法返回双向链表中指定位置处的节点,而链表中是没有下标索引的,要指定位置出的元素,就要遍历该链表,从源码的实现中,我们看到这里有一个加速动作。源码中先将index与长度size的一半比较,如果index<size/2,就只从位置0往后遍历到位置index处,而如果index>size/2,就只从位置size往前遍历到位置index处。这样可以减少一部分不必要的遍历,从而提高一定的效率(实际上效率还是很低)。

    5. LinkedList是基于链表实现的,因此插入删除效率高,查找效率低(虽然有一个加速动作)。

    6. 要注意源码中还实现了栈和队列的操作方法,因此也可以作为栈、队列和双端队列来使用。


    参考文章:http://blog.csdn.net/u013124587/article/details/52837848

    相关文章

      网友评论

          本文标题:java基础—浅析LinkedList源码

          本文链接:https://www.haomeiwen.com/subject/tmneuxtx.html