ArrayList 和 LinkedList 到底有哪些区别?

Posted 执章学长

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArrayList 和 LinkedList 到底有哪些区别?相关的知识,希望对你有一定的参考价值。

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异常。


以上是关于ArrayList 和 LinkedList 到底有哪些区别?的主要内容,如果未能解决你的问题,请参考以下文章

老徐和阿珍的故事:ArrayList和LinkedList的效率到底哪个高?

ArrayList和LinkedList学习

Java中ArrayList和LinkedList差别

ArrayList和LinkedList的区别

arraylist和linkedlist的区别

ArrayList和LinkedList的区别