Java源码 - ArrayList与LinkedList(以及堆栈)

 ArrayList是使用数组实现的,能够自动扩展大小以适应存储元素的不断增加。

 LinkedList底层是使用链表实现的。

而堆栈是使用LinkedList实现

一、ArrayList

首先看到ArrayList的继承关系。可以看出它是一个List,可clone,可序列化。

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

主要的成员变量有:


    其中elementData 就是具体的对象数组。也就是ArrayList的存储结构。

    没有什么过多好说的东西。其实就是对数组进行了封装。


我们看一下初始化分析一下动态扩容    

    初始化分为三种,1、带容量参数;2、不带容量参数;3、用一个Collection对象来构造,并将该集合的元素添加到ArrayList。




我们发现不带参数的构造方法,它并没有给ArrayList分配容量。而是引用了一个默认的空数组。当我们执行add(E),方法时,我们会发现。该方法会先核实容量大小,如果不够,则进行扩容,第一次扩容是分配默认容量(DEFAULT_CAPACITY) 10;




   grow():实际扩容算法的执行者:我们从源码中可以看到每次扩容是增加 0.5倍。



该数据结构其实就是对数据的一个封装。并且实现了动态扩容,clone 以及序列化等操作。

clonable接口以及序列化接口以后继续讨论


二、LinkedList

        一开始已经说过LinkedList是使用链表实现的。我们可以从源码中得到验证。

        LinkedList的继承关系中明确的有实现了List链表接口

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

     

  另外:我们可以用成员变量中看到,它第一部分就是一个链表信息:


  该数据结构其实就是对List的一种封装。对外提供了:增删改查等API。 

  我们拿出一个操作进行仔细看一下addLast(E e):



    addLast是调用linkLast(E e)来实现功能的。我们可以看到,其实就是对链表进行操作。


三、ArrayList与LinkedList的比较:

    相同点:都是有序结构。

    不同点:ArrayList底层使用数组存储,LinkedList底层使用链表存储

                 ArrayList增删操作时间复杂度较大;LinkedList增删操作时间复杂度较小。(得益于链表的特征优势)

                 ArrayList查询时间复杂度较小;LinkedList查询时间复杂度较小。             (得益于数组的特征优势)

    综上,他们的不同主要是因为数组与链表的差异。

四、堆栈

另外、Java现在的栈和堆数据结构,都是使用LinkedList实现。

         我们可以在LinkedeList源码最后面看到关于 栈堆的操作。


猜你喜欢

转载自blog.csdn.net/m0_37128231/article/details/80719364
今日推荐