publicclassArrayList<E> extendsAbstractList<E>
implementsList<E>, RandomAccess, Cloneable, java.io.Serializable
{privatestaticfinallong serialVersionUID = 8683452581122892189L;
//默认初始化容量privatestaticfinalint DEFAULT_CAPACITY = 10;
//内部数据结构 数组privatestaticfinal Object[] EMPTY_ELEMENTDATA = {};
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/privatestaticfinal Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access//集合长度privateint size;
//带容量的初始化public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} elseif (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
thrownew IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
//无参初始化public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//初始化集合 将其他集合元素并入该集合public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.this.elementData = EMPTY_ELEMENTDATA;
}
}
publicvoid trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size); //取size大小的数组
}
}
//保证容量大小(内部结构是数组)publicvoid ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0// larger than default for default empty table. It's already// supposed to be at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity); //保证集合容量 >= minCapacity
}
}
privatevoid ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//与默认容量相比,获取最大容量
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
//保证集合容量
ensureExplicitCapacity(minCapacity);
}
//保证集合容量privatevoid ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious codeif (minCapacity - elementData.length > 0) //如果大于集合长度
grow(minCapacity); //扩容
}
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/privatestaticfinalint MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/privatevoid grow(int minCapacity) {
// overflow-conscious codeint oldCapacity = elementData.length; //原集合长度int newCapacity = oldCapacity + (oldCapacity >> 1); // 原长度 + 原长度一半if (newCapacity - minCapacity < 0) //仍小于minCapacity,则将容量设为minCapacity
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity); //设为 Integer.MAX_VALUE// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity); //返回新数组
}
privatestaticint hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflowthrownew OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
//返回集合长度publicint size() {
return size;
}
//判断集合是否为空publicboolean isEmpty() {
return size == 0;
}
//判断集合是否含有指定元素publicboolean contains(Object o) {
return indexOf(o) >= 0;
}
//查询元素在集合的下标位置publicint indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null) //遍历数组,返回遍历到的元素下标return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1; //没有该元素
}
/**
* Returns the index of the last occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the highest index <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
* or -1 if there is no such index.
*/publicint lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
//克隆一个新的集合public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneablethrownew InternalError(e);
}
}
//将集合转化为数组public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
//将集合转化为指定类型的数组 ******// 1.当类型数组长度小于集合长度时// 返回与集合相同长度的数组,元素与集合元素相同// 2.当类型数组长度大于集合长度时,// 返回与类型数组相同长度的数组,元素与集合元素相同,但是超出部分的size下标元素为null
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
//返回指定下标的元素 查询快的原因
E elementData(intindex) {
return (E) elementData[index];
}
//返回指定下标的元素public E get(intindex) {
rangeCheck(index);
return elementData(index);
}
//将指定位置的元素置为 elementpublic E set(intindex, E element) {
rangeCheck(index); //防止下标越界
E oldValue = elementData(index); //原下标元素
elementData[index] = element; //将原下标指定为新元素return oldValue;
}
//将元素添加到集合尾(数组需要保证有足够的容量)publicboolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
returntrue;
}
//将元素插入指定位置publicvoid add(intindex, E element) {
rangeCheckForAdd(index); //防止角标越界//保证集合容量
ensureCapacityInternal(size + 1); // Increments modCount!!//将原数组从index下标开始的元素移动到index+1
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
//删除指定位置的元素public E remove(intindex) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index); //获取index角标的元素int numMoved = size - index - 1; //删除后,需要移动的元素数量if (numMoved > 0)
//将index后的元素向前移动一位
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its workreturn oldValue;
}
//移除指定元素publicboolean remove(Object o) {
if (o == null) {
for (intindex = 0; index < size; index++)
if (elementData[index] == null) { //遍历移除//将下标为index的元素移除 并将index后的元素向前移动一格
fastRemove(index);
returntrue;
}
} else { //同理for (intindex = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
returntrue;
}
}
returnfalse;
}
/*
* Private remove method that skips bounds checking and does not
* return the value removed.
*/privatevoid fastRemove(intindex) {
modCount++;
int numMoved = size - index - 1; //需要移动的元素个数if (numMoved > 0)
//将index角标后的元素向前一格移动元素
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
//清空集合publicvoid clear() {
modCount++;
// clear to let GC do its workfor (int i = 0; i < size; i++)
elementData[i] = null; //遍历 将元素都置为null
size = 0;
}
//并入其他集合的所有元素publicboolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
//保证集合容量
ensureCapacityInternal(size + numNew); // Increments modCount//将a数组的元素copy到集合中,下标为size起,长度为numNew
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
//在指定位置添加其他集合所有元素publicboolean addAll(intindex, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length; //需要添加的元素个数
ensureCapacityInternal(size + numNew); // Increments modCountint numMoved = size - index; //需要移动的元素个数if (numMoved > 0)
//将原集合index角标后长度为numMoved 移动到index+numNew(插入角标+c集合个数)处
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
//将集合c的元素添加到index角标起,长度为numNew(c集合长度)
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}