ArrayList,LinkedList和Vector的区别和优缺点
ArrayList、LinkedList和Vector都是实现了List接口。
其中,ArrayList和Vector底层是用数组实现的,因此可以用序号下标来访问他们,查找的效率高,一般数组的大小比要插入的数据大数量要大。
LinkedList的底层使用双向链表实现的,因此插入和删除的效率高。
从使用上说:
ArrayList属于非线程安全,而Vector则属于线程安全。如果是开发中没有线程同步的需求,推荐优先使用ArrayList。因此其内部没有synchronized,执行效率会比Vector快很多。
从数据结构上说:
ArrayList是一个数组结构(Vector同理),数组在内存中是一片连续存在的片段,在查找元素的时候数组能够很方便的通过内存计算直接找到对应的元素内存。但是它也有很大的缺点。我们假设需要往数组插入或删除数据的位置为i,数组元素长度为n,则需要搬运数据n-i次才能完成插入、删除操作,导致其效率不如LinkedList。 LinkedList的底层是一个双向链表结构,在进行查找操作的时候需要花费非常非常多的时间来遍历整个链表(哪怕只遍历一半),这就是LinkedList在查找效率不如ArrayList快的原因。但是由于其链表结构的特殊性,在插入、删除数据的时候,只需要修改链表节点的前后指针就可以完成操作,其的效率远远高于ArrayList。
从多线程环境上说:
三者中只有Vector是线程安全的类,自然ArrayList和LinkedList在多线程中是不安全的,但是Vector在多线程环境下使用不当也是不安全的,安全的也只是它本身而已,在Vector的方法组合使用过程中就会产生线程不安全的情况,当然还有很多种业务逻辑情况下都会造成其不安全,这里不过多赘述.有兴趣的可以自己去实验一下.例如:add方法和contains方法的组合使用在多线程中安全的是这两个方法,不是这两个方法组成的逻辑,这些坑一定要多注意.
public void xxx(Object element){
if (!vector.contains(element))
vector.add(element);
}
}
就像这种,安全的是add和contains,而不是xxx方法或者这个if域.
总结一个表格如下:
类别 | ArrayList | Vector | LinkedList |
---|---|---|---|
优点 | 适合查找 | 适合查找 | 适合插入删除 |
缺点 | 不适合插入删除 | 不适合插入删除 | 不适合查找 |
继承类 | AbstractList | AbstractList | AbstractSequentialList |
实现接口 | List, RandomAccess, Cloneable, Serializable | List, RandomAccess, Cloneable, Serializable | List, Deque, Cloneable, Serializable |
线程安全 | 否 | 是 | 否 |
数组增量 | 增量50% | 增量100%或者自定义增量 | \ |
数据结构 | 数组 | 数组(适量队列) | 双向链表 |
适用场景 | 适用于需要频繁查找元素的场景(单线程) | 适用于需要频繁查找元素的场景(多线程) | 适用于需要频繁插入删除元素的场景(单线程) |