zoukankan      html  css  js  c++  java
  • LinkedList原理分析

    LinkedList的API

    
    boolean       add(E object)
    void          add(int location, E object)
    boolean       addAll(Collection<? extends E> collection)
    boolean       addAll(int location, Collection<? extends E> collection)
    void          addFirst(E object)
    void          addLast(E object)
    void          clear()
    Object        clone()
    boolean       contains(Object object)
    Iterator<E>   descendingIterator()
    E             element()
    E             get(int location)
    E             getFirst()
    E             getLast()
    int           indexOf(Object object)
    int           lastIndexOf(Object object)
    ListIterator<E>     listIterator(int location)
    boolean       offer(E o)
    boolean       offerFirst(E e)
    boolean       offerLast(E e)
    E             peek()
    E             peekFirst()
    E             peekLast()
    E             poll()
    E             pollFirst()
    E             pollLast()
    E             pop()
    void          push(E e)
    E             remove()
    E             remove(int location)
    boolean       remove(Object object)
    E             removeFirst()
    boolean       removeFirstOccurrence(Object o)
    E             removeLast()
    boolean       removeLastOccurrence(Object o)
    E             set(int location, E object)
    int           size()
    <T> T[]       toArray(T[] contents)
    Object[]     toArray()
    

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

    LinkedList构造函数

    // 默认构造函数
    LinkedList()
    
    // 创建一个LinkedList,保护Collection中的全部元素。
    LinkedList(Collection<? extends E> collection)
    

    AbstractSequentialList简介

    在介绍LinkedList的源码之前,先介绍一下AbstractSequentialList。毕竟,LinkedList是AbstractSequentialList的子类。

    AbstractSequentialList 实现了get(int index)、set(int index, E element)、add(int index, E element) 和 remove(int index)这些函数。这些接口都是随机访问List的,LinkedList是双向链表;既然它继承于AbstractSequentialList,就相当于已经实现了“get(int index)这些接口”。

    此外,我们若需要通过AbstractSequentialList自己实现一个列表,只需要扩展此类,并提供 listIterator() 和 size() 方法的实现即可。若要实现不可修改的列表,则需要实现列表迭代器的 hasNext、next、hasPrevious、previous 和 index 方法即可。

    LinkedList与Collection关系如下图:

    img

    LinkedList的本质是双向链表。
    (01) LinkedList继承于AbstractSequentialList,并且实现了Dequeue接口。
    (02) LinkedList包含两个重要的成员:header 和 size。
      header是双向链表的表头,它是双向链表节点所对应的类Entry的实例。Entry中包含成员变量: previous, next, element。其中,previous是该节点的上一个节点,next是该节点的下一个节点,element是该节点所包含的值。
      size是双向链表中节点的个数。

    为了更了解LinkedList的原理,下面对LinkedList源码代码作出分析

    在阅读源码之前,我们先对LinkedList的整体实现进行大致说明:
    LinkedList实际上是通过双向链表去实现的。既然是双向链表,那么它的顺序访问会非常高效,而随机访问效率比较低
    既然LinkedList是通过双向链表的,但是它也实现了List接口{也就是说,它实现了get(int location)、remove(int location)等“根据索引值来获取、删除节点的函数”}。LinkedList是如何实现List的这些接口的,如何将“双向链表和索引值联系起来的”?
    实际原理非常简单,它就是通过一个计数索引值来实现的。例如,当我们调用get(int location)时,首先会比较“location”和“双向链表长度的1/2”;若前者大,则从链表头开始往后查找,直到location位置;否则,从链表末尾开始先前查找,直到location位置。
    这就是“双线链表和索引值联系起来”的方法。

    好了,接下来开始阅读源码(只要理解双向链表,那么LinkedList的源码很容易理解的)。

    img View Code

    总结
    (01) LinkedList 实际上是通过双向链表去实现的。
    它包含一个非常重要的内部类:Entry。Entry是双向链表节点所对应的数据结构,它包括的属性有:当前节点所包含的值上一个节点下一个节点
    (02) 从LinkedList的实现方式中可以发现,它不存在LinkedList容量不足的问题。
    (03) LinkedList的克隆函数,即是将全部元素克隆到一个新的LinkedList对象中。
    (04) LinkedList实现java.io.Serializable。当写入到输出流时,先写入“容量”,再依次写入“每一个节点保护的值”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。
    (05) 由于LinkedList实现了Deque,而Deque接口定义了在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(null 或 false,具体取决于操作)。

    总结起来如下表格:

            第一个元素(头部)                 最后一个元素(尾部)
            抛出异常        特殊值            抛出异常        特殊值
    插入    addFirst(e)    offerFirst(e)    addLast(e)        offerLast(e)
    移除    removeFirst()  pollFirst()      removeLast()    pollLast()
    检查    getFirst()     peekFirst()      getLast()        peekLast()
    
  • 相关阅读:
    号称简明实用的django上手教程
    转先验概率、最大似然估计、贝叶斯估计、最大后验概率
    转基于概率的矩阵分解原理详解(PMF)
    转浅谈矩阵分解在推荐系统中的应用
    转推荐算法——基于矩阵分解的推荐算法
    代码生成器的需求
    兼容性的设计要求
    API设计的需求
    有关表单的需求梳理
    element-ui table 点击分页table滚到顶部
  • 原文地址:https://www.cnblogs.com/k-class/p/13777379.html
Copyright © 2011-2022 走看看