跳至主要內容

ArrayList、LinkedList与Vector的区别

ZnyoungJava集合

区别

特性ArrayListLinkedListVector
线程安全性非线程安全线程安全线程安全
底层实现数组双向链表数组
动态扩容支持不支持支持
访问元素速度相对较慢
插入/删除速度相对较慢
接口实现ListList, DequeList
允许存放重复元素默认不允许
扩容大小当前容量的一半无扩容概念当前容量的一半
访问元素方式索引遍历链表索引

ArrayList是如何扩容的

首先,我们要明白ArrayList是基于数组的,我们都知道,申请数组的时候,只能申请一个定长的数组,那么List是如何通过数组扩容的呢?ArrayList的扩容分为以下几步:

  • 检查新增元素后是否会超过数组的容量,如果超过,则进行下一步扩容
  • 设置新的容量为老容量的1.5倍,最多不超过2^31-1 (Java 8中ArrayList的容量最大是Integer.MAX_VALUE - 8,即2^31-9。这是由于在Java 8中,ArrayList内部实现进行了一些改进,使用了一些数组复制的技巧来提高性能和内存利用率,而这些技巧需要额外的8个元素的空间来进行优化。)
  • 之后,申请一个容量为1.5倍的数组,并将老数组的元素复制到新数组中,扩容完成

为什么ArrayList非线程安全

  1. 非原子性操作:ArrayList的增加、删除和修改操作并不是原子性的,它们可能需要多个步骤来完成。在多线程环境下,如果两个线程同时对ArrayList进行修改操作,可能会导致其中一个线程的修改结果被覆盖或丢失。
  2. 不支持并发修改:当一个线程在遍历ArrayList的同时,另一个线程对ArrayList进行修改操作,可能会导致遍历操作抛出ConcurrentModificationException异常。
  3. 缺乏同步机制:ArrayList没有内置的同步机制来保证多线程操作的安全性。因此,在多线程环境下,需要使用额外的同步手段(如synchronized关键字或并发集合类)来保证ArrayList的线程安全性。
上次编辑于:
贡献者: 麦正阳