前面两篇文章对 ArrayList、LinkedList 的源码进行了分析,这篇文章对 List 做个简单的总结。
List 接口结构
List 以线性方式存储元素,其中允许存放重复元素,元素有序。主要有以下几个实现类:
ArrayList:随机访问元素效率较高,但增删元素较慢;LinkedList:增删元素效率较高,但随机访问效率较低;Vector:与ArrayList,但它是线程安全的,同步通过synchronized实现,效率较低,一般不建议使用;Stack:是一个先进先出的栈,继承自Vector;
它的主要结构如下:
数组与 ArrayList 的区别
数组与 ArrayList 之间的区别如下:
- 数组可以存储基本类型和对象;而
ArrayList只能存储对象,需要进行拆装箱。所以如果特别关注性能,可以选用数组。 - 数组需要指定大小,且不能改变;而
ArrayList可以指定或不指定初始化容量,且支持自动扩容。所以,如果数据大小已知,并且对数据的操作比较简单,可以使用数组。 ArrayList最大的优势就是封装了很多操作数组的方法。如果操作比较复杂,可以选用ArrayList。- 表示多维数组时,用数组更加直观。例如
Object[][]。
其实一般来说,在普通业务开发中,直接使用 ArrayList 就可以了,相比于损耗一点点性能,换来使用上的方便简单,也是可以接受。
但如果做的是较底层的开发,如中间件,性能优化等,数组一般会比较好。
ArrayList 与 LinkedList 的区别
ArrayList
优点:ArrayList 底层基于动态数组实现,由于地址连续,按照下标直接计算操作地址,随机访问效率较高。
缺点:但同样是因为地址连续,在插入和删除数据时,数组需要移动数据,所以插入和删除操作的效率较低。
LinkedList
优点:LinkedList 底层基于双向链表实现,由于地址是任意的,所以在创建节点时比较简单,增加和删除操作的效率比较高。另外,它也适用于队列、栈形式的场景。
缺点:由于 LinkedList 访问元素时需要一个一个地移动指针,所以随机访问的效率较低。
适用场景
可以按照如下要求进行选择:
- 如果对数据随机访问的操作较多,则选用
ArrayList。 - 如果对数据的增加或删除操作较多,则选用
LinkedList。
ArrayList 与 Vector 的区别
ArrayList 和 Vector 很相似,主要有以下三个区别:
Vector是线程安全的,而ArrayList不是。Vector中的方法被synchronized修饰,效率很低,一般不赞成使用。- 两者都是基于动态数组实现,但是扩容时,两者的增加方式不同。
ArrayList每次扩至1.5倍,而Vector扩至2倍。 Vector可以设置扩容时的自增容量capacityIncrement,而ArrayList不可以。ArrayList支持Iterator和ListIterator迭代器;而Vector除此之外,还支持Enumeration。
它们的适用场景如下:
Vector是线程安全的,而ArrayList是非线程安全的。如果在非多线程的情境下,一般采用ArrayList效率比较高。由于Vector效率较低,如果在多线程环境下,一般使用CopyOnWriteArrayList。