美文网首页
源码阅读 - LinkedList

源码阅读 - LinkedList

作者: 烟小花飞花 | 来源:发表于2018-04-13 11:22 被阅读0次

    0. 什么是LinkedList

    • 双向链表
    • 非线程安全

    1. 实现的本质

    链表,Node<E> first指向链表头部,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;
        }
    }
    

    2. 主要api解析

    2.1 构造函数

    1. 无参,构建空链表
    2. 参数是一个集合,会将集合中的数据放到链表中
    /**
     * 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);
    }
    

    2.2 add方法

    add方法有以下几种

    //在最后添加
    public boolean add(E e)
    //在指定位置添加
    public void add(int index, E element)
    public boolean addAll(Collection<? extends E> c)
    public boolean addAll(int index, Collection<? extends E> c)
    public void addFirst(E e)
    public void addLast(E e)
    
    /**
     * Appends the specified element to the end of this list.
     *
     * <p>This method is equivalent to {@link #addLast}.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    
    /**
     * 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++;
    }
    //===========================================================================
    /**
     * Inserts the specified element at the specified position in this list.
     * Shifts the element currently at that position (if any) and any
     * subsequent elements to the right (adds one to their indices).
     *
     * @param index index at which the specified element is to be inserted
     * @param element element to be inserted
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public void add(int index, E element) {
        checkPositionIndex(index);
        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
    
    /**
     * Inserts element e before non-null Node succ.
     */
    //将节点插入index位置
    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++;
    }
    
    /**
     * Returns the (non-null) Node at the specified element index.
     */
    //返回指定位置的node,由于是双向链表,所以如果index在前半段从first开始查找,如果在后半段则从last开始查找
    //类中所有关于index的定位都是通过此方法进行
    Node<E> node(int index) {
        // assert isElementIndex(index);
        //前半段,从first开始搜
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        //后半段,从last开始搜
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }
    

    2.3 remove方法

    //和revmoeFirst()相同
    public E remove()
    //删除指定位置节点
    public E remove(int index)
    //删除从first开始的第一个data为o的节点,这里使用equals进行比较
    public boolean remove(Object o)
    public E removeFirst()
    //和remove(Object o)相同
    public boolean removeFirstOccurrence(Object o)
    public E removeLast()
    //删除从last往前的第一个data为o的节点
    public boolean removeLastOccurrence(Object o)
    

    2.4 get方法

    使用node方法进行定位,然后返回值

    /**
     * Returns the element at the specified position in this list.
     *
     * @param index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
    

    2.5 遍历

    可使用listIterator进行遍历。
    还提供了一个类只做倒序遍历,也是通过ListItr实现的。

    /**
     * Adapter to provide descending iterators via ListItr.previous
     */
    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();
        }
    }
    

    3. 参考

    1. 源码 build 1.8.0_121-b13版本
    2. LinkedList源码解析 http://www.cnblogs.com/ITtangtang/p/3948610.html

    相关文章

      网友评论

          本文标题:源码阅读 - LinkedList

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