ArrayList 和 LinkedList 是 List 接口的两种不同实现,并且两者都是线程不安全的。对于这两者的区别无非就是围绕着增删查改的效率来说
1.底层结构的不同
(1)ArrayList
ArrayList内部使用的动态数组来存储元素,同时数组也属于顺序结构的线性表,逻辑上和物理上都是连续的。
(2)LinkedList
LinkedList 内部使用的双向链表来存储元素,可当作堆栈、队列、双端队列使用,逻辑上是连续的,但是在物理(真实的内存上)上不一定连续。
2.插入元素
(1)ArrayList
ArrayList插入元素时会涉及到移动元素,所以时间复杂度为O(n),但是在末尾插入时不需要移动,时间复杂度为O(1)。
(2)LinkedList
LinkedList添加元素时,可以进行头插法和尾插法。头插法,直接就可以插入时间复杂度为O(1),而尾插法,需要先遍历一遍链表找到尾巴在进行插入所以时间复杂度为O(n)。但是不管是头插还是尾插,都不需要移动元素。
总结:在增加一个元素的时候,如果我们都用头插的方式,那么LinkedList更好一点,不需要移动元素,所以顺序表一般不会用在频繁的插入元素的场景下。LInkedList的插入更方便,随用随取,而ArrayList如果满了后,还需要扩容,可能会浪费内存。
3.删除元素
(1)ArrayList
删除第一个元素,时间复杂度为O(n),删除最后一个元素,时间复杂度为O(1)。但同时伴随着删除也会发生数据的移动。(但是从整体上来说,不可能每次都是删除最后一个元素,所以整体上来看,时间复杂度O(n))。
(2)LInkedList
最好情况下删除头结点,时间复杂度为O(1),删除别的位置,需要遍历找到该位置,所以时间复杂度为O(n)。(但是从整体上来说,不可能每次都是删除头结点,所以整体上来看,时间复杂度也是O(n))。但是只需要修改指向。
4.查找元素
(1)ArrayList
大多数情况下,查找元素的时间复杂度为O(1),因为我们可以通过数组下标查找。但是如果要找的是某一个数据,必须要从头到尾遍历这个元素,那么时间复杂度就为O(n)
(2)LInkedList
大多数情况下,查找元素是需要遍历链表,所以时间复杂度为O(n);
5.修改元素
(1)ArrayList
如果给定下标,那么通过下标修改元素,时间复杂度为O(1);
(2)LInkedList
由于没有下标,所以你要修改元素,必须先找到这个元素进行修改,所以时间复杂度为O(n)
那么什么时候用LInkedList,和ArrayList呢?
从整体上来说,添加或者删除元素,LInkedList表现更加,并且不用移动数据。查找或者修改元素,ArrayList表现更佳,可以通过下标直接访问。
ArrAyList空间连续、支持随机访问。但是 1.中间或前面部分的插入删除时间复杂度O(N) 2.增容的代价比较大。
LInkedList以节点为单位存储,不支持随机访问。但是1.任意位置插入删除时间复杂度为O(1) 2.没有增容问题,插入一个开辟一个空间。