集合框架系列(三)LinkedList源码分析-Java8

一、LinkedList简介

LinkedList的底层是一个双向的链表。链表的优点是加入一个元素,链表长度增加1,不会有冗余。

二、构造方法

1、LinkedList()

仅创建LinkedList对象,底层的链表为空。

2、LinkedList(Collection<? extends E> c)

将集合对象转换为数组,再将数组中的元素加入链表中,成为链表中的节点。

三、节点

LinkedList链表节点对象是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;
        }
    }

四、插入元素

插入元素(LinkedList.add(E))通过新建节点实现:

新建一个节点,将入参元素加入节点内。将节点放在原链表的最后一个位置,并更新链表最后一个位置的节点为这个新建的节点。

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

LinkedList.addFirst(E)方法是用来增加一个节点到链表首部,源码与上面的方法类似,需要注意的是:两种方法新建节点时,Node对象构造方法参数有些区别。在链表首部插入节点方法的源码比较简单,不再赘述。

五、获取元素

LinkedList通过索引查找元素的效率比ArrayList慢,LinkedList先判断索引处于链表的前半部分还是后半部分。如果索引处于前半部分,则从首节点开始向后查找;如果索引处于后半部分,则从尾节点开始向前查找。

六、移除元素

先看张图:

  1. 将要删除节点前一个节点对象的下一个节点变量,指向要删除节点后一个节点;
  2. 将要删除节点后一个节点对象的上一个节点变量,指向要删除节点前一个节点;
  3. 要删除的节点此时已脱离链表,等待GC回收。

七、LinkedList与ArrayList的区别

  1. ArrayList的底层是一个可变数组,LinkedList底层是一个链表;
  2. ArrayList通过索引查找元素的效率高,时间复杂度为O(1);LinkedList通过索引查找元素的效率慢,时间复杂度为O(n);
  3. LinkedList插入删除元素的效率高,ArrayList插入删除元素的效率慢。

猜你喜欢

转载自my.oschina.net/u/2896303/blog/1799813