有关LinkedList常用方法的源码解析


jdk1.7.0_79

  上文里解析了有关ArrayList中的几个常用方法的源码——《有关ArrayList常用方法的源码解析》,本文将对LinkedList的常用方法做简要解析

  LinkedList是基于链表实现的,也就是说它具备了链表的优点和缺点,随机访问慢、插入删除速度快。既然是链表,那么它就存在节点数据结构,也不存在容量大小的问题,来一个在尾部添加一个。

//LinkedList$Node
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;
    }
}

  第一个默认不带参数的构造方法,构造一个空链表。

//1.LinkedList,默认构造方法
public LinkedList() {
}

  第二个构造方法能把一个集合作为一个参数传递,同时集合中的元素需要是LinkedList的子类

//2.LinkedList,能将一个集合作为参数的构造方法
public LinkedList(Collection<? extends E> c) {
    this();
    addAll(c);
}

  两个构造方法都比较简单,接下来看元素的插入及删除等方法。

public boolean add(E e) {
    linkLast(e);    //将元素添加到链表尾部
    return true;
}
//LinkedList#linkLast
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++;    //链表数据总数+1
    modCount++;    //modCount变量在《有关ArrayList常用方法的源码解析》提到过,增删都会+1,防止一个线程在用迭代器遍历的时候,另一个线程在对其进行修改。
}

  学过《数据结构》的同学相信看到链表的操作不会感到陌生,接着来看看删除指定位置的元素remove(int)方法。

//LinkedList#remove
public E remove(int index) {
    checkElementIndex(index);    //检查是否越界 index >= 0 && index <= size
    return unlink(node(index));    //调用node方法查找并返回指定索引位置的Node节点
}

//LinkedList#node,根据索引位置返回Node节点
Node<E> node(int index) {
    
    if (index < (size >> 1)) {    //size >> 1 = size / 2,如果索引位于链表前半部分,则移动fisrt头指针进行查找
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {    //如果索引位于链表后半部分,则移动last尾指针进行查找
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

  查找到index位置的Node,调用unlink方法摘掉该节点

//LinkedList#unlink,一看即懂
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;
}

  从代码中就能看出LinkedListArrayList两者的优缺点,由于只涉及简单的链表数据结构,所以不再对其他方法进行解析。

优质内容筛选与推荐>>
1、bmp24位彩色图像转8位灰度图像(纯C++)
2、PLSQL
3、requests库和robots.txt标准
4、[Codeforces 1205B]Shortest Cycle(最小环)
5、Java数据结构--基于数组的队列


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn