Listing list is actually the source code analysis.

Source: Internet
Author: User
Tags addall

In the previous article "arraylist is actually the source code analysis of a single incident", I will talk about arraylist for you. So this time, I will show you the list of collections in the same list family. Let's look at the source code directly below:

public class LinkedList<E>    extends AbstractSequentialList<E>    implements List<E>, Deque<E>, Cloneable, java.io.Serializable{    transient int size = 0;        //Node 是LinkedList的一个内部类,下面贴出了这个内部类的源码,     //主要用于保存上一个、当前和下一个元素的引用        //头(第一个)元素    transient Node<E> first;    //尾(最后一个)元素    transient Node<E> last;    public LinkedList() {    }    //构造方法传入Collection, 那么将Collection转换为链表结构    public LinkedList(Collection<? extends E> c) {        this();        addAll(c);    }        public boolean addAll(Collection<? extends E> c) {        return addAll(size, c);    }            /**     * 内部类     */    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 boolean addAll(int index, Collection<? extends E> c) {        //index >= 0 && index <= size        checkPositionIndex(index);        Object[] a = c.toArray();        int numNew = a.length;        if (numNew == 0)            return false;        //succ保存的是index位置的元素        Node<E> pred, succ;        if (index == size) {            //当index == size 的时候, 当前元素的上一个元素就是之前已存在链表的最后一个元素            //(如果觉得有点绕, 可以再好好体会一下)            succ = null;            pred = last;        } else {            //当index != size 的时候, 那么index就一定出现在之前链表中            //此处的调用的node方法,下面源码也已经给出,            //node方法的主要作用就是判断index所处位置是在之前链表的上半部分还是下半部分,            //在上半部分就从第一个元素开始循环,循环到index位置时返回元素, 如果是在后半部分,那么就从最后一个元素往前循环,循环到index位置时返回元素            succ = node(index);            //得到index所在元素的上一个元素引用            pred = succ.prev;        }                //别急,上面还在热身, 这儿才开始转换                for (Object o : a) {            @SuppressWarnings("unchecked") E e = (E) o;            //构造Node对象, 此时Node对象持有对前一个元素以及当前元素的引用            Node<E> newNode = new Node<>(pred, e, null);            if (pred == null)                //如果前一个元素为null, 那么说明之前不存在链表,此元素将设置为链表的第一个元素                first = newNode;            else                //如果已存在链表,那么就从之前链表的index位置开始插入                pred.next = newNode;            pred = newNode;        }        if (succ == null) {            last = pred;        } else {            pred.next = succ;            succ.prev = pred;        }        size += numNew;        modCount++;        return true;    }        private void checkPositionIndex(int index) {        if (!isPositionIndex(index))            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));    }        private boolean isPositionIndex(int index) {        return index >= 0 && index <= size;    }        //上面已经把这方法解释了一遍,这儿就不多说了,贴出来就为了让大家看得直观    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;        }    }                //下面开始分析常用的add 、 remove 方法        //先看看add方法    public void add(int index, E element) {        checkPositionIndex(index);                //相信通过上面的分析,你已经能够猜到add 改怎么做了,        //当index == size的时候, 已存在链表的最后一个元素就是当前待插入元素的上一个节点(元素)        //当index != size的时候, 老规矩,先找出index位置的节点元素, 然后再插入(上面已经详解,这儿只做概述,加深印象)        if (index == size)            linkLast(element);        else            linkBefore(element, node(index));    }        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) {        // 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++;    }            //接下来再看看remove方法    public E remove(int index) {        checkElementIndex(index);        return unlink(node(index));    }        //此方法作用: 先得到index位置的node, 然后拿到其上一个元素(pre)和下一个元素(next),    //将上一个元素(pre)的下一个元素设置为index的next, 此时,就成功的删除了index位置的元素,    //举个例子吧: 李四左手牵着张三,右手牵着王五, 现在我们要删除李四, 那么只需要直接将张三的手牵向王五, 明白了吧    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;    }            }

Through code analysis, we can see that the linked list is actually implemented based on a two-way linked list. Therefore, do not remember the features of the linked list mentioned in the book. It is right to know the features of the linked list, so far, we have to talk about the differences between the arraylist and arraylist:

Arraylist is implemented based on arrays. Therefore, arraylist has the following features: ordered, repeatable elements, slow insertion, and fast indexing;

The slow list is implemented based on a two-way linked list, so it has the characteristics of fast table insertion and slow index;

After learning about their features, you can select an appropriate list based on your actual needs.

Listing list is actually the source code analysis.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.