ArrayList和HashMap、LinkedList一样,是常用的数据结构。ArrayList提供了一个动态数组,弥补了数组的长度固定,增加元素操作消耗大的不足。但因为ArrayList存储了对象数组,构造对象也造成了性能开销,所以相对布言,如果数组的长度可知,使用数组的效率最高,反之则可使用ArrayList。
ArrayList内部使用Object[]存储数据
private transient Object[] elementData;
ArrayList使用Obect数组elementData来存储数据,这样可以存储任意类型的数据。
构造函数
public ArrayList() {
this(10);
}
默认构造函数的数组的容量为10。
ArrayList添加元素
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
添加元素时,元素添加到ArrayList容器的尾部。
在添加元素之前,先判断数组的容量是否需要扩容ensureCapacity(size+1),传的参数是当前数组的size+1。
确保ArrayList容器容量
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
在ensureCapacity方法中,先把参数(新索引值)minCapacity与数组容器的原长度oldCapacity做比较,如果参数minCapacity大于原长度,就说明数组已经饱和,需要进行扩容。
扩容的具体实现是把原来的长度增加50%再增加1,然后,把旧数组的数据拷贝到新数组里(使用System.arrayCopy()实现)。
在指定位置(index)添加元素
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
ensureCapacity(size+1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
实现流程也是先判断数组需不需要扩容,然后把从index往后面的数组元素,向后移动一位。再把index位置的数组元素的引用赋予要插入的元素。
查找指定位置(index)的元素
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
}
查找元素的方法比较简单,先是查看索引index值是否越界,如果在范围之内,直接返回数组的该索引元素。
从数组的指定位置index删除元素
public E remove(int index) {
RangeCheck(index);
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
在ArrayList中删除指定位置的元素时,如果这个index不是数组的最大下标位置,就把index之后的所有元素向前移动一位,来填充index位置的元素移除后的空白。
总结:
ArrayList是一个动态数组数据结构,可以灵活地添加元素,查找性能好,而在指定位置添加和删除元素时性能下降,因为要移动数组的数据。所以ArrayList适用于查找多,而在数组内指定位置操作少的场景。