• ArrayList 和 LinkedList 到底有哪些区别?


    ArrayList 和 LinkedList

    ArrayList 和 LinkedList 之前有那些区别?这个是面试中最常见的一个问题之一了。跟着源码分析,看看两者之间的区别。

    底层数据结构不同

    进入 ArrayList 的源码,可以看到 ArrayList 的成员变量有一个 Object 数组,这个数据就是用来存放插入的数据。
    在这里插入图片描述
    同样进入 LinkedList 的源码,可以看到成员变量维护者两个节点,一个是 first 节点,一个是 last 节点,实际上,LinkedList 底层是一个双向链表。
    在这里插入图片描述

    操作集合的底层实现不同

    插入操作

    很容易理解,底层的数据结构不同,直接影响了操作集合的底层操作就是不同的,这里可能需要你对数据结构有一定的了解。

    首先是插入,根据我们学过的数据结构的知识,我们知道数组中的元素是存储在一个连续的空间中的,而链表则不是。因此根据索引查找的情况,数组只需要根据偏移量就可以立马查找到数据,这里我们结合源码看。

    以下是 ArrayList 的 add 方法
    在这里插入图片描述
    首先当然是需要判断插入时 index 索引是否合法,插入的索引只能是[0,size],这也很容易能够理解,否则就容易造成数组越界。
    在这里插入图片描述
    接着调用 System 的 arraycopy 方法,这个方法是一个 navite 方法,说明这个方法不是由 Java 实现的,实现的效果是将数组A的复制到数组B,并且指定区间,这里是将要插入的 index 之后的数据(包括index指向的数据),全都往后移动一位。
    例如:数组[1,2,3,4],index = 2,操作后就会变为[1,2,3,3,4]。

    在这里插入图片描述
    接着就是将元素插入到 index 的位置,然后 size++。

    以下是 LinkedList 的 add方法

    在这里插入图片描述
    首先,是先判断插入的位置是否是尾端,如果是尾端,直接插入即可,因为是双链表,我们自然维护着最后一个节点的引用。
    在这里插入图片描述
    如果是遇到插入到中间的情况,也就是最普遍的情况,则是先要获取到插入的节点的引用,然后再插入。而获取到插入节点的引用也非常有意思,因为我们知道,我们既拥有头指针,也拥有尾指针,因此我们只要判断插入的索引是靠近哪一个,然后再从这个端点开始遍历。这里size>>1的效果等同于size/2
    在这里插入图片描述

    删除操作

    对于 ArrayList 的删除,首先是找到目标元素,然后再将后面的元素全部往前移动。
    在这里插入图片描述
    对于 LinkedList 的删除,首先同样是遍历到要删除的节点,然后直接调用unlink 方法将该节点断开即可。
    在这里插入图片描述
    通过 unlink 方法断开掉要删除的节点。
    在这里插入图片描述

    按照索引查找

    对于 ArrayList 来说,无非只需要检查一下参数是否合法,然后返回数组的对应元素即可。
    在这里插入图片描述
    在这里插入图片描述

    而对于 LinkedList 来说,除了判断参数是否合法外,需要先找到该索引的节点(通过遍历),然后才能返回对应这个节点的值。

    在这里插入图片描述
    在这里插入图片描述

    总结:其实对于 ArrayList 和 LinkedList 的最大差异,就是底层数据结构的不同,导致在执行同个操作的时候时间效率不一样,比如如果需要频繁按照索引查找元素,则适合使用 ArrayList ;如果是需要频繁删除或者添加元素,则适合使用 LinkedList ,因为 ArrayList 需要移动大量元素,当然 LinkedList 在删除元素前还需要一次遍历进行定位,因此这也不止绝对的。而对于存储空间的选择,实际上 ArrayList 的空间开销主要是在数组上,当然由于扩容机制,会导致数组会有一定的预留空间;而对于 LinkedList 的空间开销主要是在前驱节点和后继节点上,因此每个元素的空间消耗要比 ArrayList 更多。

    关于线程安全

    ArrayList 和 LinkedList 都是不保证线程安全的。在进行各种操作时并没有上锁,迭代器获取下一个元素的时候会检查是否被修改,如果被修改则抛出ConcurrentModificationException异常。

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    10. 机器学习-评测指标
    JVM:(二)类加载子系统
    linux下使用selenium调用谷歌浏览器的一些问题
    JS进阶第二篇:函数参数按值传递
    Java“牵手”京东商品详情数据,京东商品详情API接口,京东API接口申请指南
    武田公司2022财年第一季度业绩强劲;正稳步实现全年的管理层指引目标
    渗透测试工具(3)Burpsuite
    字符编码
    【无标题】
    Cannot resolve MVC view ‘xxx‘
  • 原文地址:https://blog.csdn.net/PaperJack/article/details/127778828