ArrayList
实现List接口底层为数组,与java中数组相比容量可以动态增加
特点
- 线程不安全
- 元素有序
- 插入元素可为null
- 查询快,增删满
首先介绍两个常见的方法
Arrays.copyOf()
从源数组中获得指定长度的数组,返回一个新数组
//调用copyOf(T[] original, int newLength)时newType默认为original类型
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
//如果newLength比源数组长则新数组剩余值为类型默认值
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
native方法,首先检查src、dest是否为数组类型,再判断是否越界,最后进行复制
复制数组src,以srcPos为起始位置(包括),长度为length的数据到dest数组以destPos为起始位置(包括)长度为length的位置
ArrayList类
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
//默认初始容量
private static final int DEFAULT_CAPACITY = 10;
//空对象数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//缺省空对象数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//存放当前集合中元素的数组
transient Object[] elementData;
//当前集合大小
private int size;
//构造器,数组初始默认为空,开始添加时扩容为DEFAULT_CAPACITY
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//构造指定大小数组
public ArrayList(int initialCapacity)
//首先判断容量是否超出限制,在当前size+1添加元素
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
//扩容过程
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//如果当前数组为空则返回Math.max(10,size+1)
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
//结构修改次数加1,判断容量是否超出限制,超出则调用grow
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//新容量大小为old+old>>1,增加原容量的一半
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
//初始时newCapacity为0,默认大小为minCapacity 10
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//最大为Integer.MAX_VALUE
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//创建一个容量为newCapacity的新数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
//指定位置添加,首先判断索引是否在数组长度范围内,然后确定容量是否充足
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1);
//将[index,size)复制到[index+1,size+1),相当于index之后(包括)数据都后移一位
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
//在index插入元素
elementData[index] = element;
size++;
}
//删除index位置的元素
public E remove(int index) {
//检查索引是否在数组范围内
rangeCheck(index);
//结构修改次数加1
modCount++;
//返回的删除值
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
//将index之后的元素统一前移一位
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//置为null,GC回收
elementData[--size] = null;
return oldValue;
}
//for循环遍历equals比较 删除
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;
}
//数组置null,size置0
public void clear() {
modCount++;
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
}