ArrayList
Arraylist底层是用数组实现的存储
特点是查询效率高,增删效率低,线程不安全,使用频率高
线程不安全使用的原因是:在我们日常使用过程中,查询占绝大多数,不会涉及到频繁的增删,如果涉及到频繁的增删,我们可以使用LinkedList,如果需要线程安全就要使用Vector,三者的区别就是这样。
底层实现是数组,数组是定长的,如果不断添加数据,会有什么问题
ArrayList可以通过构造方法在初始化的时候指定底层数组的大小,当初始化的时候不赋予初始大小,那么数组容量就是0,当真正需要add数据的时候,会分配DEFAULT_CAPACITY = 10的初始容量
数组长度是有限制的,而ArrayList是可以存放任意数量对象,长度不受限制,那么他是怎么实现的呢
是通过数组扩容的方式去实现,有一个长度为10的数组,要新增元素,如果已经满了,会重新定义一个长度为10+10/2的数组就是新增一个长度为15的数组,然后把原数组的数据,原封不动的复制到新数组中,再把原数组的地址换到新数组,这样就扩容了。
ArrayList默认初始容量为10
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
1.7与1.8的区别
1.7之前初始化的时候调用this(10)才会给ArrayList容量,1.7及以后默认是个空数组,从第一次add的时候容量才会变成10
ArrayList增删慢,增删的时候都做了什么,为什么慢
有两种新增方式,第一种是指定index新增, 第二种是直接新增,在这之前会用ensureCapacityInternal方法校验一下容量是否足够,如果容量不够,是要先扩容的。
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
ArrayList(int initialCapacity)会不会初始化数组⼤⼩?
会初始化数组,但List大小没有变
ArrayList插入删除一定慢吗
取决于删除的元素离数组末端有多远,ArrayList作为堆栈来用是很合适的,push和pop操作不涉及数据的移动操作
ArrayList删除
和新增一样都是copy一个数组,比如删除index5的数据,那就copy index5+1到结束位置的数据放到index5的位置上,就完成了index5位置数据的删除
ArrayList是线程安全的么?
不是,线程安全版本的数组容器是Vector
Vector的实现是在所有的方法上加synchronized
ArrayList⽤来做队列合适么?
队列⼀般是FIFO(先⼊先出)的,如果⽤ArrayList做队列,就需要在数组尾部追加数据,数组头部删除 数组,反过来也可以。 但是⽆论如何总会有⼀个操作会涉及到数组的数据搬迁,这个是⽐较耗费性能的。
结论:ArrayList不适合做队列。
那数组适合用来做队列么?
适合
ArrayList的遍历和LinkedList遍历性能比较如何?
遍历ArrayList要⽐LinkedList快得多,ArrayList遍历最⼤的优势在于内存的连续性,CPU的内部缓存 结构会缓存连续的内存⽚段,可以⼤幅降低读取内存的性能开销。