1. 简述
ArrayList底层是用数组实现的存储。特点是查询效率高,增删效率低,线程不安全,平常开发使用频率很高。
2. 为什么线程不安全还使用它?
因为平常开发所使用的场景中,大多数都是用来查询,不会设计太频繁的增删;如果涉及频繁的增删,可以使用LinkedList;如果需要线程安全就是用Vector,这就是三者的区别。
不存在一个集合工具是查询效率又高,增删效率又高,还是线程安全的。因为数据结构的特性就是优劣共存的,想找个平衡点很难,牺牲了性能,那就安全;牺牲了安全那就快速。
3. ArrayList的构造器
ArrayList可以通过构造方法在初始化的时候指定底层数组的的大小。
通过无参构造方法的方式ArrayList()初始化,则赋值底层数Object[] elementData为一个默认空数组Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}所以数组容量为0,只有真正对数据进行添加add时,才分配默认DEFAULT_CAPACITY = 10的初始容量 。
4. ArrayList扩容
假设有一个长度为10的数组(已满),当再去添加一个元素时,就需要扩容。
- 重新定义一个长度为10+10/2的数组(长度为15)
- 将原数组原封不动的复制到新的数组中
- 再把指向原数组的地址指向新的数组
5.ArrayList的默认大小是多少?
10
6. ArrayList如何添加元素的?
有两种add方法:可以直接新增;或者指定index新增。直接添加有一步校验长度的过程ensureCapacityInternal,长度不够,则需扩容。
7. public ArrayList(int initialCapacity) 会不会初始化数组大小?
不会,只有多次使用add()方法。
这是Java Bug里面的一个经典问题
8. ArrayList插入删除一定很慢吗?
不一定。比如在最后一位添加元素、删除最后一个元素
9.ArrayList是线程安全的吗?
不是,线程安全的数组是Vector。它的实现非常简单,就是把所有方法统统加上 synchronized 。
10. ArrayList用来做队列合适吗?
队列一般是先进先出。 如果用ArrayList做队列,就需要在数组尾部追加数据,数组头部删除数组,反过来也是。
这个比较耗费性能,所以不适合做队列。
11.数组适合用来做队列吗?
数组是非常合适的。
比如ArrayBlockingQueue内部实现就是一个环形队列,它是一个定长队列,内部是用一个定长数组来实现的。
12. ArrayList的遍历和LinkedList遍历性能比较如何?
ArrayList要比LinkedList快得多,ArrayList遍历最大的优势在于内存的连续性,CPU的内部缓存结构会缓存连续的内存片段,可以大幅度降低读取内存的性能开销。