前言
在日常开发过程中,Collection 接口下的List 接口是一个常用到的接口。 本篇文章介绍了List 的特点以及其具体实现子类之间的区别。希望能对大家使用List 的时候有所帮助。
一、List的特点
List 是一种存放单列数据的集合,可以存放同一种类型的元素、元素之间有序、元素允许重复的集合,集合中每个元素都有其对应的顺序索引。List 中的元素都有对应的一个序列号(索引)记录着元素的位置,因此可以通过这个序列号快速访问指定位置的元素。- 在
List 接口内部定义了一些除Collection 接口已有方法之外的新方法。比如get,indexOf,subList,lastIndexOf等方法。
二、List的具体实现类
List 接口的实现类有:ArrayList 、LinkedList 、Vector 。
1. ArrayList
内部存储用的数据结构是用**数组(动态调整大小)**实现,默认初始容量为10。每次扩容大小是增加50%(在java8版本以及之后的版本,java6使用的是1.5倍)。
- 优点:使用数组实现,因此内部元素可以通过索引实现快速随机访问(检索集合中特定索引位置的元素)。
- 缺点: 1. 从
ArrayList 中间位置插入和删除元素,都需要循环移动其他元素元素的位置。2. 数组空间不够需要扩容时,会开辟一个新的数组把旧的数组元素拷贝过去,比较耗性能。3.线程不安全。 - 扩容
- java 8 及之后扩容计算方法:
int newCapacity = oldCapacity + (oldCapacity >> 1); 这意味着在原来数组大小的基础上扩大50%作为新数组容量的大小 - java 6 的计算方法:
int newCapacity = (oldCapacity * 3)/2 + 1; 这意味着在原来数组大小的基础上扩大1.5倍作为新数组容量的大小
2. LinkedList
内部存储用的数据结构是用双向链表实现。
- 优点:使用链表实现,适合动态的插入和删除。
- 缺点:1.随机访问元素的速度相对较慢。2.基于链表数据结构的实现,占用的内存空间比较大(除了保存数据本身,还要保存指针信息)。
3. Vector
基于 数组(动态调整大小) 数据结构实现,初始容量是10。
- 优点:线程安全
- 缺点:效率低,增加元素、删除元素、查找元素都很慢。
三、实现类之间的比较
1. ArrayList和LinkedList性能差别的原因
-
随机访问方面(随机访问指检索集合中特定索引位置的元素) ArrayList可以根据索引直接找到值并返回; 而LinkedList的随机访问是先判断 location 的值是不是大于中间索引的值,如果大于从链表的后面开始查找,反之从前面开始查找。所以在随机访问方面ArrayList是比LinkedList强的。 -
随机插入、删除方面 因为ArrayList的底层实现是数组,所以在随机插入、删除时,需要移动大量的数据,造成效率低下。而LinkedList的随机插入、删除,它是先找到插入点,然会直接在插入点后面直接插入即可,其中查找插入点的过程中还有一个加速的过程,插入点如果小于中间索引值,那么从前面开始查找,反之从后面开始查找。所以,在随机插入、删除方面ArrayList的效率比不上LinkedList。
2. ArrayList与Vector之间的比较
- 线程安全方面:
Vector是线程安全的,也就是说,在同一时间只有一个线程可以访问Vector对象。而ArrayList是线程不安全的,就是说,在同一时间可以有多个线程访问ArrayList对象。例如,如果一个线程正在执行添加操作,那么在多线程环境中可能会有另一个线程执行删除操作。 - 性能方面:
ArrayList更快,因为它是不同步的(线程不安全的),而Vector操作由于是同步的(线程安全的),所以性能更慢。如果一个线程在访问Vector,它就获得了一个锁,那其他想要操作Vector的线程就必须等着,直到锁被释放才能访问Vector。 - 数据增长方面:
ArrayList与Vector的底层都是基于数组(动态调整大小)实现的。它们都会动态增长和缩小,从而保持最合适的存储空间大小。但是它们在重新调整大小的方式是不同的。如果元素数量超过了容量,ArrayList会增加当前数组的50%,而Vector会增加100%。 - 日常使用方面:
如果没有特别要求一定要使用Vector,一般都偏向于用ArrayList。即使在要求线程安全的时候,也可以通过使用显式Collections.synchronizedList 这个方法。
四、使用场景
1. ArrayList的使用场景
从以上对ArrayList 的优缺点比较中可以知道,ArrayList 的使用场景是:
- 其拥有动态数组的属性,适合在声明时不知道数据结构大小时使用,避免了浪费内存空间
- 适合需要快速随机查找和遍历
- 不适合经常需要插入和删除操作
2. LinkedList的使用场景
从以上对LinkedList 的优缺点比较中可以知道,LinkedList 的使用场景是:
- 适合需要随机插入、随机删除效率要求比较高时
- 可以作为队列和栈使用
3. Vector的使用场景
- 一般在开发中很少用到这个Vector。Vector 是jdk1.0时候加入的,存在的意义可能是为了兼容性。
五、总结
这篇简短的文章,大致总结了List的特点,它的具体实现类及这些实现类之间一些方面的比较,最后给出了一些使用场景。 以上内容并不一定全面准确,只是个人的学习记录,如果需要了解更全面、详细的信息,请务必自行查阅更多资料。
|