ArrayList和LinkedList的区别
1、数据结构不同
2、效率不同
3、扩容机制不同
4、开销不同
1.数据结构不同
ArrayList底层使用的是一个动态数组而LinkedList底层使用的是一个双向链表
2.效率不同
在不同的场景下ArrayList和LinkedList各有各的优点,在增加和删除元素时LinkedList效率会比ArrayList快很多,但是在查询和修改时就会比ArrayList慢很多,这主要是两者数据结构不同的原因
数组由于每个值都有对应的索引所以在查询和修改时可以通过索引快速定位到需要查询或修改的元素进行查询或修改,而不需要像双向链表一样从头开始迭代找到指定的值才可以开始操作
而双向链表结构是没有索引可以进行定位的,他就是一条链表,所以他想要查询或者修改某个元素的时候就需要从头开始遍历,才可以找到他所有需要查询或者修改的元素随后进行修改和返回
LinkedList在debug时看见的数据结构
List<String> list = new LinkedList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
可以看到的是A节点中的next直接指向了B节点、B节点中的next指向了C节点、C节点中的next指向了D节点
D节点中的pre指向了C节点、C节点中的pre指向了B节点、B节点中的pre指向了A节点,由此形成了一条双向链表
链表修改过程
第一点可以看到的是原本有A、B、C、D四个元素他们都具有双向联系,A指向B的同时B也指向了A,B指向C的同时C也指向了B,C指向D的同时D也指向了C。
第二点我们在B和C之间插入了一个E,这个时候我们只需要改动B和C的指向关系就可以直接在中间插入一个元素了,而不需要像数组一样挪动指定位置后的所有元素
链表删除过程
链表的删除过程也只需要改动相关元素的前后指向就可以达到删除效果了,如上图我们删除C元素,就只需要直接给B指向D,D指向B同时给C置为Null(为了垃圾回收)就可以了,而不需要像数组一样给要删除的元素挪动到最后在给数组容量减一来达到删除效果。
3.扩容机制的不同
- 双向链表无需扩容,只需要修改给元素关联起来形成一条链表就可以了不存在既定的容量,所以也就不存在扩容这一说法。
- 数组在到达指定长度是需要创建一个新的数组,并且长度比之前那个数组要大的数组,并给需要扩容的数组的数据存入进去以此来达到扩容的目的
4.开销不同
- 双向链表的开销浪费主要体现在由于每个元素都存储了他前一个和后一个元素之间的关系所以在空间开销是会很大。
- 数组的开销浪费主要体现在要预留一定的空间。
总结
- ArrayList是实现是基于动态数组的,LinkedList基于双向链表的。
- 在查询和修改时,ArrayList优于LinkedList,因为LinkedList每次都需要从头开始遍历才可以。
- 对于新增和删除操作,LinedList比较占优势,因为ArrayList要移动数据。