基础
数组列表,主要用来装在数据。
和它类似的还有LinkedList,ArrayList查找和访问元素的速度较快,但是新增、删除比较慢
为什么线程不安全还在使用?
底层是数组,数组是定长的,不断添加元素不会有问题吗?
- ArrayList可以通过构造方法初始化的时候初始化底层数组的大小
- 默认初始化一个数组容量为0的空数组,只有真正add的时候,才分配默认DEFAULT_CAPACITY = 10的初始容量。
扩容机制
一个长度为10的数组,新增一个元素,发现已经满了
- 重新定义一个长度10+ 10/2的数组,也就是新增一个长度为15的数组
- 把原来数组的数据,原封不动的复制到新的数组中,这个时候再把原数组的地址指向新数组,这样ArrayList就完成了一次改头换面。
为什么初始长度是10?
好像是调研之后,10这个长度最常用最有效率。没啥其他原因,8、12也没啥。10比较圆满ArrayList增删元素怎么做的?为什么慢?
新增元素
新增元素的时候,有根据index新增的,也有直接新增的。在这之前先检验长度的判断,如果长度不够,就需要扩容。
1.8 底层采用了位运算。
如果是指定位置新增,会先复制一个数组,然后再把元素放进去,后面的所有元素都得复制,如果再涉及扩容,就更慢了。删除元素
删除元素一定慢吗?
看删除的元素离数组末端有多远。
删除怎么实现的?
ArrayList(int initialCapacity)会初始化数组大小吗?
会。但是list.size() == 0
数组初始化了,但是list没有,size没变
demo
public static void main(String[] args) {
List<String> list = new ArrayList<>(10);
System.out.println(list.size());
list.add(5, "6");
}
ArrayList适合做队列吗?
队列一般都是先进先出(FIFO), 如果用ArrayList做队列,就需要数组尾部追加数据,数组头部删除数组,反过来也可以。但是任何一个操作都会涉及数组的数据搬迁,比较耗费性能。 结论:不适合。
数组适合做队列吗?
适合。比如ArrayBlockingQueue,内部就是一个环形队列,是一个定长队列,内部就是用一个定长数组来实现的。
简单来说就是用两个偏移量来标记数组的读位置和写位置,如果超过长度就折回出数组开头,前提是他们是定长数组。
ArrayList和LinkedList遍历性能比较?
ArrayList比LinkedList快很多。ArrayList遍历的最大优势在于内存的连续性,CPU的内部缓存结构会缓存连续的内存片段,大幅度降低读取内存的开销。