ArrayList类是List接口的实现类,ArrayList可以看成一个动态数据,可以根据大小动态变化。由于其数组的底层结构,所以它的访问速度非常快,删除和插入操作较慢。
下图是ArrayList类在Collection集合框架中的结构图,蓝线代表继承关系,绿线代表接口实现
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
ArrayList支持泛型
// 版本号,不用管
private static final long serialVersionUID = 8683452581122892189L;
// 数组默认的初始容量
private static final int DEFAULT_CAPACITY = 10;
// 用于创建一个空的实例
private static final Object[] EMPTY_ELEMENTDATA = {};
// 用于保存List数据的数组
private transient Object[] elementData;
// 数组大小
private int size;
ArrayList中有两个重要的属性:elementData 和 size
elementData是Object[]类型的数组
elementData前面有个transient关键字,Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
// 构造器一
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
// 构造器二
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
// 构造器三
public ArrayList(Collection c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
// Collection中定义的API
boolean add(E object)
boolean addAll(Collection collection)
void clear()
boolean contains(Object object)
boolean containsAll(Collection collection)
boolean equals(Object object)
int hashCode()
boolean isEmpty()
boolean remove(Object object)
boolean removeAll(Collection collection)
boolean retainAll(Collection collection)
int size()
T[] toArray(T[] array)
Object[] toArray()
// AbstractCollection中定义的API
void add(int location, E object)
boolean addAll(int location, Collection collection)
E get(int location)
int indexOf(Object object)
int lastIndexOf(Object object)
ListIterator listIterator(int location)
ListIterator listIterator()
E remove(int location)
E set(int location, E object)
List subList(int start, int end)
// ArrayList新增的API
Object clone()
void ensureCapacity(int minimumCapacity)
void trimToSize()
void removeRange(int fromIndex, int toIndex)
从方法列表中可以发现:
- remove() 方法有两个,传参不同返回值也不同,一个根据数组元素值删除返回是否成功,一个根据索引位置删除返回删除的值
- 同样add()、remove()也有两个
//
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 判断是否需要扩容,并扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// 获取当前数组大小
int oldCapacity = elementData.length;
// 获得扩容后的数组大小:原来的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
// 完成扩容
elementData = Arrays.copyOf(elementData, newCapacity);
}
// 添加单个元素
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 进行扩容检查
elementData[size++] = e;
return true;
}
// 在指定位置添加元素
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // 扩容检查
// 将index位置后面的数组元素统一后移一位,把index位置空出来
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
// 添加一个集合
public boolean addAll(Collection c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // 扩容检查
// 复制数组,将C添加到elementData尾部
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
// 在指定位置添加一个集合
public boolean addAll(int index, Collection c) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size);
Object[] a = c.toArray();
int numNew = a.length ;
ensureCapacity( size + numNew); // 扩容检查
int numMoved = size - index;
// 数组复制,空出第index到index+numNum的位置,即将数组index后的元素向右移动numNum个位置
if (numMoved > 0)
System. arraycopy(elementData, index, elementData, index + numNew,
numMoved);
// 将要插入的集合元素复制到数组空出的位置中
System. arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
// 读取索引位置的元素
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
// 根据索引位置删除
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
// 复制移动数组,覆盖index位置
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // 把移动后空出的位置置为null
return oldValue;
}
// 根据元素值删除
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
// 调用快速删除方法
fastRemove(index);
return true;
}
}
return false;
}
// 快速删除
private void fastRemove(int index) {
modCount++;
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
}
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size);
}
}
ArrayList类中很多其他方法,比较简单基本上都是通过for循环进行数组的操作,就不进行分析了。