1、ArrayList和LinkedList的区别
- 相同点:都是List接口的实现类,有序、有重复值
- 不同点:
- 底层数据结构不同
- ArrayList是基于数字实现的
- LinkedList是基于双向链表实现的
- 扩容方式不同
- ArrayList:当数组容量不足时,按照原容量的1.5倍进行扩容增长
- LinkedList:由于采用链表结构,每次添加元素都会创建新的Node节点并分配空间,所以不存在扩容
- 插入和删除元素不同
- ArrayList:采用数组存储,插入删除元素时会产生元素移动,所以性能较差
- LinkedList:采用链表存储,插入删除元素时不会产生元素移动,所以性能较高
- 底层获取元素方式不同
- ArrayList:可以通过下标快速访问某一个元素
- LinkedList:元素需要从头或者尾部遍历链表来获取元素
- 适用场景不同
- ArrayList:适用于数据连续性遍历,读多写少的场景
- LinkedList:适用于数据的频繁增删操作,读少写多的场景
- RandomAccess接口
- ArrayList实现了RandomAccess接口,LinkedList没有实现RandomAccess接口
- 使用Collections.binarySearch查找元素时,ArrayList使用indexedBinarySearch(基于下标的二分查找),而LinkedList使用iteratorBinarySearch(基于迭代器的二分查找)。可以理解为ArrayList支持随机高效访问,LinkedList不支持
- 内存空间占用不同
- ArrayList:会预留一定的容量空间
- LinkedList:每一个元素都需要消耗比ArrayList更多的空间(因为需要存放 pre + next + data)
- 底层数据结构不同
2.ArrayList和Vector的区别
- 相同点:ArrayList和Vector底层都是使用数组实现的。
- 不同点:
- 线程安全性不同
- ArrayList:线程是不安全的
- Vector:线程是安全的
- 初始容量不同
- ArrayList:初始默认容量为0,添加第一个元素时扩容为10
- Vector:初始默认容量为10
- 扩容方式不同
- ArrayList:在原有容量的基础上,扩容0.5倍
- Vector:按照自定义扩容或者在原有容量的基础上扩容1倍
- 性能不同
- ArrayList:性能较高
- Vector:性能较低(被synchronized(同步锁)修饰)
- 线程安全性不同
3.ArrayList的扩容方式
- 使用无参构造方法创建ArrayList时,实际上初始化赋值的是一个空数组。当向数组中添加第一个元素时,数组容量扩容为10
- 当数组容量不足时,调用grow()方法进行扩容,每次扩容后容量都会变为原来的1.5倍(在原基础上扩容0.5倍)
- 最大容量为Integer.MAX_VALUE或Integer.MAX_VALUE-8
4.LinkedList的适用场景
- 适用于需要频繁进行插入和删除操作的场景,因为在LinkedList中,插入和删除一个节点只需要改变指针的指向,而不需要移动其他节点。
- 适用于数据量较大,内存限制较小的场景,因为LinkedList在内存中不需要一次性分配连续的空间,而是每个节点在堆内存中独立分配。这样就比数组更加灵活,可以根据需要动态地分配和释放内存空间。