Java 中 ArrayList、LinkedList 和 Vector 的区别

Java 中 ArrayListLinkedListVector 是编程中经常使用的集合类,他们之间的区别也是经常在面试中会问到的问题。下面就底层实现执行效率线程安全性两个方法来看看三者的区别。

区别

底层实现

实现接口:

  • ArrayListVector实现了 java.util.RandomAccess 接口;
  • LinkedList实现了 java.util.Deque 接口。

底层实现:

  • ArrayListVector的底层是基于动态数组实现的;
  • LinkedList的底层是基于双向链表实现的。

执行效率

ArrayList

ArrayList的底层是基于动态数组实现的,所以 ArrayList 拥有着数组的特性。

  • 优点:根据下标随机访问数组元素的效率高,向数组尾部添加元素的效率高。
  • 缺点:删除数组中的数据以及向数组中间添加数据效率低,因为需要移动数组;当长度大于初始长度的时候,每添加一个数,都会需要扩容。

  

LinkedList

LinkedList的底层是基于双向链表实现的,所以 LinkedList 拥有着链表的特性。

  • 优点:添加、删除元素的效率高,只需要改变指针指向即可。
  • 缺点:访问元素的平均效率低,需要对链表进行遍历。

Vector

VectorArrayList 一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写 Vector,但实现同步需要很高的花费,因此,访问它比访问 ArrayList 慢。

线程安全性

在多线程并发的时候,ArrayListLinkedList 是非线程安全的,并且是不同步的。Vector 的所有方法都用了 synchronized 关键字修饰,是线程安全的,但是 Vector 中的方法组合起来使用不是线程安全的。

Vector 创建的 Iterator,虽然和 ArrayList 创建的 Iterator 是同一接口,但是,因为 Vector 是同步的,当一个 Iterator 被创建而且正在被使用,另一个线程改变了 Vector 的状态(例如,添加、删除元素),这时调用 Iterator 的方法时将抛出 ConcurrentModificationException,因此必须捕获该异常。

总结

底层实现 线程安全性 执行效率 引进版本
ArrayList 动态数组 非线程安全 随机访问、向尾部添加元素的效率高;删除、向中间添加元素效率低 JDK 1.2
LinkedList 双向链表 非线程安全 添加、删除元素效率高;访问元素的平均效率低 JDK 1.2
Vector 动态数组 线程安全 ArrayList,但是比 ArrayList 效率低 JDK 1.0
  • ArrayListVector 的实现是基于动态数组,LinkedList 的实现是基于双向链表。
  • 对于随机访问,ArrayList 优于 LinkedListArrayList 可以根据下标以 O(1) 时间复杂度对元素进行随机访问。而 LinkedList 的每一个元素都依靠地址指针和它后一个元素连接在一起,在这种情况下,查找某个元素的时间复杂度是 O(n)。
  • 对于插入和删除操作,LinkedList 优于 ArrayList,因为当元素被添加到 LinkedList 任意位置的时候,不需要像 ArrayList 那样重新计算大小或者是更新索引。
  • LinkedListArrayList 更占内存,因为 LinkedList 的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。
  • 在多线程并发的时候,ArrayListLinkedList 是非线程安全的,并且是不同步的,Vector 是线程安全的,但是 Vector 中的方法组合起来使用不是线程安全的。

评论
 上一篇
Java 中 equals() 和 hashCode() 的作用 Java 中 equals() 和 hashCode() 的作用
java.lang.Object 类中定义了 equals() 和 hashCode() 方法,Object 类是所有 Java 类的基类,所以所有的 Java 类都实现了这两个方法。 equals()equals() 方法的作用是用来判断
2019-02-18
下一篇 
Java 中 String、StringBuilder 和 StringBuffer 的区别 Java 中 String、StringBuilder 和 StringBuffer 的区别
Java 中 String、StringBuilder、StringBuffer 是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题。下面就运算速度(运算性能或执行效率)和线程安全性两个方法来看看三者的区别。 区别运算速
2019-02-12
  目录