1.ArrayList是实现List接口的一个类,实现了List接口的所有方法,允许添加所有元素,NULL也可以加入进来。底层是通过数组实现的。它定义的大小是可变的。Arraylist除了线程是不安全的,其他大体上和vector相等。
2.ArrayList的方法里面的get(),set(),Iterator(),ListIterator()这几个方法的时间复杂度是常数(constant)。The add operation runs in amortized constant time;adding n elements requires O(n) time.然后其他的方法大体上是以线性的时间总计。ArrayList有自己增加大小的能力,当我们向里面添加数据的时候,它总是先检查里面的大小是否够用,如果大小不足,那么它将新建一个连续的内存区域,大小为之前的1.5倍,然后把之前的内容拷贝到新的数组里,因为ArrayList底层是通过数组实现的,然后把要添加的内容放在拷贝内容的后面。然后之前的ArrayList引用变量则指向新的ArrayList对象,原来的ArrayList对象由于没有引用变量指向它,它则在一个不确定的时刻被垃圾回收线程回收回去。
3.ArrayList是线程不安全的,如果我们想建一个线程安全的ArrayList,可以这样新建:List list=Collections.SynchronizedList(New ArrayList());这样则可以实现线程的安全。
4.ArrayList查询时比数组稍微较为慢一点,因为是调用get()方法,而数组则是直接用[]下标,相当于直接操作内存地址,所以运行的速度就比较快了。并且ArrayList可以存储对象,而数组只能存储基本数据类型,这也是它们其中的区别。
5.ArrayList对象使用add,或者remove方法的时候,需要“整体移动”,这样就很消耗内存,效率就很低了。下面我来看下remove方法的源码:
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
解析:删除指定位置的元素,首先判断你的参数是否大于数组的范围,然后删除指定的位置数据,接着把删除位置后面的数据整体往前一定一个位置,最后把最后一个元素置空,防止内存泄漏。