JAVA源码分析-LinkedList(一)

1 篇文章 0 订阅

一、概述

LinkedList是一种线性表,它是一种抽象数据类型(ADT),基于双向链(doubly linked list)表实现。

二、继承关系图

注意:其中红色线为内部类(inner class)。

三、双向链表

双链表:每一个节点的头部指向上个节点,尾部指向下一个节点,中间储存着当前data。通过如图的方式连接起来。

第一个元素的prev节点为null,最后一个元素的next节点为null。

添加操作:新建new node,将last节点的next设置为新节点,这样新节点成为last。

删除操作:将被删除节点的上一个节点的next设置为被删除元素的next,将被删除节点的下一个元素的prev设置为被删除节点的prev。

节点的代码实现(摘自JDK1.8版本):

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

Node类是LinkedList的一个内部类(inner class)。这个类实现了双链表的节点。item指向当前元素,next指向下一个节点,prev指向上一个节点,通过一个全参构造函数可以新建一个链表节点。因为这种特殊的构造,所以LinkedList只需要储存第一个节点和最后一个节点即可以将全部节点链接起来。JDK源码中的first字段和last字段就是双链表的头和尾。这两个字段被transient修饰,无法被序列化(在后续会讲到LinkedList序列化的问题)。

    /**<p>摘自JDK1.8</p>
     * Pointer to first node.
     * Invariant: (first == null && last == null) ||
     *            (first.prev == null && first.item != null)
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     * Invariant: (first == null && last == null) ||
     *            (last.next == null && last.item != null)
     */
    transient Node<E> last;

插入操作的实现代码实现:将被添加的元素添加到链表尾部。原理即为上面讲到的插入操作。元素也可以插入。

    /**<p>摘自JDK1.8</p>
     * 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++;    //该字段的作用会在后面章节讲到
    }

删除操作的代码实现:

 /**<p>摘自JDK1.8</p>
     * Removes the first occurrence of the specified element from this list,
     * if it is present.  If this list does not contain the element, it is
     * unchanged.  More formally, removes the element with the lowest index
     * {@code i} such that
     * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
     * (if such an element exists).  Returns {@code true} if this list
     * contained the specified element (or equivalently, if this list
     * changed as a result of the call).
     *
     * @param o element to be removed from this list, if present
     * @return {@code true} if this list contained the specified element
     */
    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;
    }

unlink(Node<E> x)方法:

/**
     * Unlinks non-null node x.
     */
    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;
    }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值