ArrayList、LinkedList、Vector是集合中经常拿来比较和面试的一个问题,我这里简要概括一下他们的区别和实现原理。
存储结构
ArrayList和Vector是按照顺序将元素存储(从下表为0开始),删除元素时,删除操作完成后,需要使部分元素移位,默认的初始容量都是10.
ArrayList和Vector是基于数组实现的,LinkedList是基于双向链表实现的(含有头结点)。
线程安全性
ArrayList不具有有线程安全性,在单线程的环境中,LinkedList也是线程不安全的,如果在并发环境下使用它们,可以用Collections类中的静态方法synchronizedList()对ArrayList和LinkedList进行调用即可。
Vector实现线程安全的,即它大部分的方法都包含关键字synchronized,但是Vector的效率没有ArraykList和LinkedList高。
扩容机制
从内部实现机制来讲,ArrayList和Vector都是使用Object的数组形式来存储的,当向这两种类型中增加元素的时候,若容量不够,需要进行扩容。ArrayList扩容后的容量是之前的1.5倍,然后把之前的数据拷贝到新建的数组中去。而Vector默认情况下扩容后的容量是之前的2倍。
Vector可以设置容量增量,而ArrayList不可以。在Vector中,有capacityIncrement:当大小大于其容量时,容量自动增加的量。如果在创建Vector时,指定了capacityIncrement的大小,则Vector中动态数组容量需要增加时,如果容量的增量大于0,则增加的是大小是capacityIncrement,如果增量小于0,则增大为之前的2倍。
在这里需要说一下可变长度数组的原理:当元素个数超过数组的长度时,会产生一个新的数组,将原数组的数据复制到新数组,再将新的元素添加到新数组中。
增删改查的效率
ArrayList和Vector中,从指定的位置检索一个对象,或在集合的末尾插入、删除一个元素的时间是一样的,时间复杂度都是O(1)。但是如果在其他位置增加或者删除元素花费的时间是O(n),LinkedList中,在插入、删除任何位置的元素所花费的时间都是一样的,时间复杂度都为O(1),但是他在检索一个元素的时间复杂度为O(n).
所以如果只是查找特定位置的元素或只在集合的末端增加移动元素,那么使用ArrayList或Vector都是一样的。如果是在指定位置的插入、删除元素,最好选择LinkedList