LinkedList源码按摩,啊舒服

​首先看一下LinkedList的声明

public class LinkedList<E>    extends AbstractSequentialList<E>    implements List<E>, Deque<E>, Cloneable, java.io.Serializable{}

AbstractSequentialList 分析

官方文档的解释如下

  This class provides a skeletal implementation of the <tt>List</tt>  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), <tt>AbstractList</tt> should be used  in preference to this class.<p>

意思大概就是对于随机访问的数据或者数组,应优先使用AbstractSequentialList,即

E get(int index) E set(int index, E element)void add(int index, E element)E remove(int index)boolean addAll(int index, Collection<? extends E> c)

上面的这几个接口都是随机访问的

 

实现List<E>可以有list的特性

实现Deque,可以使用双端队列访问元素的方法,是一个双向链表

实现Cloneable,可以实现克隆对象的全部元素

实现java.io.Serializable,可以实现序列化

 

常量

 

// 元素个数transient int size = 0;// 指向头指针transient Node<E> first;// 指向末尾指针transient Node<E> last;

 

构造方法

    // 无参构造方法,生成空的链表    public LinkedList() {    }    // 构建一个包含指定元素集合的列表,顺序有Collection的iterator返回    public LinkedList(Collection<? extends E> c) {      this();      addAll(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;        }    }

 

头节点插入

   /**    * 头节点插入元素e    * 先拿到当前头结点定义为f,定一个新的节点newNode,pre指向null,元素为e,next指向f    * 在修改新的头节点为newNode    * 判断拿到的头节点f是否为空,如果为空last为newNode,此时链表就一个元素newNode    * 如果不为空,f的pre节点指向newNode新创建的节点    * size ++     * modCount 涉及修改数据结构都要修改的值,即修改统计数,用来实现fail-fast机制    */        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;        else            f.prev = newNode;        size++;        modCount++;    }
 

末尾节点添加元素

    /**    * 末尾节点添加元素e    * 获取当前尾部节点last为l    * 定义新节点newNode,pre为l,元素为e,next为null    * 定义现在last尾部节点为newNode    * 如果刚才首次获取尾部节点l为null,头部节点改为newNode,此时链表就y一个元素    * 如果不为null,l的next节点就为我们的newNode    * 元素个数添加    * 修改次数添加,和上面类似    */    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++;    }

在非null元素succ之前插入元素

    /**    * 在非null元素succ之前插入元素e    * 拿到succ的pre节点pred    * 创建newNode节点保存我们要插入的数据,pre为刚才取得pred节点,元素为e,next为succ    * 修改succ的pre节点为创建的newNode节点    * 判断如果pred拿出的为null,即pred就是头节点,first为newNode    * 不为null,pred的next节点为新创建的newNode    * 修改元素个数size    * 修改次数添加    */    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++;    }

取消链接非空的第一个节点

  /**  * 取消第一个节点f的链接  * 取出f节点元素element  * 取出f的后置节点next  * 然后把f的元素值置为null,next置为null,置为nullgc更快回收  * 链表的头节点定义为刚才取出的后置节点next  * 判断next节点是否为空,如果为null,last也为null,链表为k空  * 不为null next的前置节点置为null  * 元素个数减少1  * 修改次数添加  */  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;        f.next = null; // help GC        first = next;        if (next == null)            last = null;        else            next.prev = null;        size--;        modCount++;        return element;    }

取消链接的最后一个节点

   /**   * 取消链接的最后一个非k空节点l   * 取出l节点的元素element   * 取出l节点的前置节点prev   * l元素置为null,pre前置节点置为null   * 链表的last置为f节点的pre节点prev   * 判断如果pre节点为null,链表first头节点为null   * 不为null,prev的后置节点置为null断开元素的链接   * 元素个数减少1   * 修改次数添加   */   private E unlinkLast(Node<E> l) {        // assert l == last && l != null;        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;    }

取消链接非空节点

   /**   * 取消链接非空节点x   * 分别取到x节点的元素值element,前置节点prev,后置节点next   * 如果元素x的前置节点为null,链表的first 指向next节点,如果不为null,prev节点的next执行元素x的next节点   * 如果元素x的后置节点为null,链表的last节点为x的prev前置节点,不为null,元素x后置节点的pre指向x的前置节点   * x元素值置为null   * 元素减少1   * 修改次数添加   */   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;    }

 

获取链表的第一个元素

    /**    * 拿到first指向的元素    * 判断是否为null,为null抛出NoSuchElementException()list为空异常    * 不为null,返回f.item的元素本身    */    public E getFirst() {        final Node<E> f = first;        if (f == null)            throw new NoSuchElementException();        return f.item;    }

获取链表的最后一个元素

    /**    * 根据last拿到链表的最后一个元素值    * 判断last是否为null,如果为null,返回list为空的异常    * 不为null,返回l.item元素本身    */    public E getLast() {        final Node<E> l = last;        if (l == null)            throw new NoSuchElementException();        return l.item;    }

删除链表中第一个元素并返回

    /**    * 拿到first第一个元素    * 如果为null,抛出list为empty的异常    * 不为null调用unlinkFirst(f)方法来取消元素的链接    */    public E removeFirst() {        final Node<E> f = first;        if (f == null)            throw new NoSuchElementException();        return unlinkFirst(f);    }

删除链表中最后一个元素并返回

    /**    * 根据last获取链表的最后一个元素    * 如果为null,抛出list为empty的异常    * 不为null调用unlinkLast(l)方法,取消最后一个元素的链接    */    public E removeLast() {        final Node<E> l = last;        if (l == null)            throw new NoSuchElementException();        return unlinkLast(l);    }

指定元素添加到链表头部

    /**    * 直接调用linkFirst(e)方法添加    */    public void addFirst(E e) {        linkFirst(e);    }

指定元素添加到链表尾部

    /**    * 调用linkLast(e)方法尾部添加元素e    */    public void addLast(E e) {        linkLast(e);    }

判断链表中是否包含元素

    /**    * 判断链表是否包含元素o    * 调用indexOf(o)方法,indexOf方法见下面解析,返回元素的索引,找不到或者索引不存在返回-1    */    public boolean contains(Object o) {        return indexOf(o) != -1;    }

indexOf(Object o)

    /**    * 返回元素o在此链表中 【首次】出现的位置    * 如果list不包含元素o,返回-1    * 更正式的说,返回元素的索引,如果索引值不存在返回-1    */    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;    }

获取list元素个数

    public int size() {        return size;    }

添加一个元素

    /**    * 添加一个元素e    * 调用linkLast(e)在队列的尾部添加元素    * 返回true    */    public boolean add(E e) {        linkLast(e);        return true;    }

删除一个元素

   /**   * 如果元素o存在的话,移除首次出现的元素,即最小索引的元素,   * 如果元素o为null,移除首次出现的null元素   * 如果元素o不在list中,不做任何改变   * 如果元素o匹配上,调用unlink(o)方法来删除元素   */   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;    }

addAll 方法添加指定的集合元素

    public boolean addAll(Collection<? extends E> c) {        // 从什么位置开始添加,此处从原list的末尾开始添加元素集合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;}

清空list,删除所有的元素

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

get(index)

    /**    * 返回指定位置的元素    * 检测index索引是否有效    * 返回index索引位置元素    */    public E get(int index) {        checkElementIndex(index);        return node(index).item;    }

指定位置覆盖原先位置元素

    /**    * 检验index是否有效    * 获取index位置节点    * 替换node节点item    */    public E set(int index, E element) {        checkElementIndex(index);        Node<E> x = node(index);        E oldVal = x.item;        x.item = element;        return oldVal;    }

指定位置后面添加元素(原索引位置元素以及之后的元素右移,索引位置放置新元素)

    /**    * 校验index索引是否有效    * 判断如果index等于list数组元素数量,就调用linkLast(element) 尾部添加元素    * 不等于就调用linkBefore(elemetn,node(index))在元素之前插入    */    public void add(int index, E element) {        checkPositionIndex(index);        if (index == size)            linkLast(element);        else            linkBefore(element, node(index));    }

移除元素

    /**    * 校验index索引是否有效    * 调用unlink(node)方法取消链接    */    public E remove(int index) {        checkElementIndex(index);        return unlink(node(index);    }

 

好了,LinkedList源码按摩就到此结束了,如有错误欢迎指出,共同进步,以便下次提供更好的按摩服务

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值