List:可重复
List是Collection的子接口,其中也可以保存各个重复的内容,同时,它也是非常常用的数据类型。一共有三个实现类,分别是ArrayList、Vector和LinkedList。
1. ArrayList:Object数组
ArrayList是使用最为广泛的实现类,其底层是用数组实现的,可以认为 ArrayList 是一个可改变大小的数组,与普通数组的区别就是它是没有固定大小的限制。增删慢,查询快,属于非线程安全的操作类。
- ArrayList 提供了对List的add()方法,可以将元素插入到指定位置的 arraylist 中。
- ArrayList 提供了对List的remove()方法,可以删除 arraylist 里的单个元素。
- ArrayList 提供了对List的get()方法,可以通过索引值获取 arraylist 中的元素。
ArrayList 中的元素必须是连续存储,当需要在 ArrayList 的中间位置插入或者删除元素时,列表中剩余的元素都会被移动,这代表它的修改代价较高,因此 ArrayList 不适合随机插入和删除的操作,更适合随机查找和遍历的操作。
ArrayList 是线程不安全的集合类,当多线程环境下,并发对同一个 ArrayList 执行add,可能会抛出java.util.ConcurrentModificationException的异常。
ArrayList 不需要在定义时指定数组的长度,在数组长度不能满足存储要求时,ArrayList 会创建一个新的更大的数组并将数组中已有的数据复制到新的数组中。
2. Vector:Object数组
Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的:在开发中 ArrayList 性能较高,属于异步处理,而 Vector 性能较低,是同步处理的,即同一时刻只允许一个线程对 Vector 进行操作(新增、删除、修改),以保证多线程环境下数据的一致性,但需要频繁地对 Vector 实例进行加锁和释放锁操作,因此其读写效率比 ArrayList 低。增删慢,查询快,属于线程安全的操作类。
3.LinkedList:双向循环链表
LinkedList 表示的是一个链表的操作类,即Java中已经为开发者提供好了一个链表程序,开发者直接使用就好,无须重新开发。内部数据结构基于双向链表结构存储元素,在对LinkedList进行插入和删除操作时,根据链表的特性插入删除,故随机访问速度很慢,还提供了在List接口中未定义的方法,用于操作链表头部和尾部的元素,因此有时可以被当做堆栈和队列使用。增删快,查询慢,属于非线程安全的操作。
4.关于List的面试问题
- 什么是List?List包括什么? List是一个有序的集合,继承于Collection接口,除了Collection通用的方法以外,扩展了部分只属于List的方法。List定义的元素是有序的且可重复的。List包括ArrayList、Vector和LinkedList三个实现类。
- ArrayList的优缺点?
- ArrayList优点: ArrayList底层以数组实现,支持随机访问(因为ArrayList实现了RandomAccess接口); ArrayList在顺序添加一个元素的时候非常方便;
- ArrayList的缺点: 在删除或者插入元素的时候,需要做一次复制操作,如果操作的元素很多的话,会比较耗费性能;
- ArrayList与LinkedList有什么异同?
- ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;
- Arraylist 底层基于动态数组;LinkedList 底层基于双向循环链表结构;
- 在增删(非首尾)时,LinkedList 效率要优于 Arraylist ;
- LinkedList 不支持高效的随机元素访问,而ArrayList 实现了RandmoAccess 接口,所以有随机访问功能。
- LinkedList 更占用内存,LinkedList 存储两个引用,一个指向前一个元素,一个指向后一个元素。
- ArrayList和Vector的区别是什么? 1、Vector类的所有方法都是同步的。可以由两个线程安全地访问一个 Vector 对象、但是一个线程访问 Vector 的话代码要在同步操作上耗费大量的时间,所以 ArrayList 在性能方面要优于Vector。Arraylist 是异步处理,所以在不需要保证线程安全时时建议使用 Arraylist 。 2、ArrayList 和 Vecto r都会根据实际需要动态的调整容量,只不过在 Vector 扩容每次会增加1倍,而ArrayList只会增加50%。