关闭

JAVA集合源码分析系列:LinkedList源码分析

336人阅读 评论(0) 收藏 举报
分类:

LinkedList源码分析

一.LinkedList简介

LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。 
LinkedList 实现 List 接口,能对它进行队列操作。 
LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。 
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。 
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。 
LinkedList 是非同步的。

二.LinkedList源码分析

LinkedList的本质是双向链表。 
(01) LinkedList继承于AbstractSequentialList,并且实现了Dequeue接口。 
(02) LinkedList包含两个重要的成员:header 和 size。 
header是双向链表的表头,它是双向链表节点所对应的类Entry的实例。Entry中包含成员变量: previous, next, element。其中,previous是该节点的上一个节点,next是该节点的下一个节点,element是该节点所包含的值。 
size是双向链表中节点的个数。 
   
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。注意LinkedList的内部不是循环的。

1.Node

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.item = element;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.next = next;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.prev = prev;
        }
    }
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

这是一个节点对应的类,其中可看到有一个元素、该节点的前驱、该节点的后继三个成员。

2.add方法

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">
 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">add</span>(E e) {
        linkLast(e);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
    }
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

add方法其实是在链表的最后又添加了一个元素。我们可以看一下linkLast的源码:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * Links e as last element.
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> linkLast(E e) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Node<E> l = last;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Node<E> newNode = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Node<>(l, e, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>);
        last = newNode;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (l == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>)
            first = newNode;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
            l.next = newNode;
        size++;
        modCount++;
    }
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>

大致意思就是在链表的尾部再增加一个元素。

三.总结

大学的时候学习的《数据结构》又派上用场了,通过上面的分析,我们知道LinkedList的内部实现是双向链表,优点是:增加删除方便,但是取值比较慢,正好和ArrayList相反。请选择合适的尝试使用合适的数据结构。

参考资料

Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例 
http://www.cnblogs.com/skywang12345/p/3308807.html

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    大量干货公众号

    个人资料
    • 访问:72695次
    • 积分:956
    • 等级:
    • 排名:千里之外
    • 原创:22篇
    • 转载:2篇
    • 译文:0篇
    • 评论:464条
    文章分类