Java集合(5)之 List 总结

221 阅读3分钟

前面两篇文章对 ArrayListLinkedList 的源码进行了分析,这篇文章对 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 的区别

ArrayListVector 很相似,主要有以下三个区别:

  • Vector 是线程安全的,而 ArrayList 不是。Vector 中的方法被 synchronized 修饰,效率很低,一般不赞成使用。
  • 两者都是基于动态数组实现,但是扩容时,两者的增加方式不同。ArrayList 每次扩至 1.5 倍,而 Vector 扩至 2 倍。
  • Vector 可以设置扩容时的自增容量 capacityIncrement,而 ArrayList 不可以。
  • ArrayList 支持 IteratorListIterator 迭代器;而 Vector 除此之外,还支持 Enumeration

它们的适用场景如下:

  • Vector 是线程安全的,而 ArrayList 是非线程安全的。如果在非多线程的情境下,一般采用 ArrayList 效率比较高。由于 Vector 效率较低,如果在多线程环境下,一般使用 CopyOnWriteArrayList