public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{ //序列号UID,代表版本,私有的静态常量
private static final long serialVersionUID = 8683452581122892189L;
/**
*定义数组初始化默认长度为10,静态常量
*/
private static final int DEFAULT_CAPACITY = 10;
/**
*用于空实例的数组,静态私有的,空实例意味着创建时为,空,
*类型为object(相当于泛型,即任何类型都可以)
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 用于默认大小的空实例的共享空数组实例。我们
将其与EMPTY_ELEMENTDATA区分开来,以便知道何时膨胀多少
添加第一个元素。
静态私有数组对象常量
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* 存储ArrayList元素的数组缓冲区。
ArrayList的容量是这个数组缓冲区的长度。任何
空ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
当添加第一个元素时是否扩展为DEFAULT_CAPACITY */
transient Object[] elementData; // non-private to simplify nested class access
/**
* ArrayList的大小(包含的元素数量)。
* 私有的int类型,默认为0
*
* @serial
*/
private int size;
/**
* 构造器
*
* @param initialCapacity 参数initialCapacity为arraylist容量
* @throws 如果参数容量为负数,则抛出异常IllegalArgumentException
//如果传递的参数长度>0,给数组缓冲区赋值长度,长度为传递的参数长度
//如果传递参数长度为0,将empty_elementdata这个空数组给elemendata
//如果传递参数小于0,将抛出IllegalArgumentException,这个异常
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
/**
*无参构造,这个arraylist的初始长度为10
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 构造一个包含指定集合元素的列表,按照集合的迭代器返回元素的顺序 *
* @param 参数:是个集合。集合中包括要将其元素放置到arraylist中
* @throws如果指定传递参数的集合元素为空,则抛出空指针异常
//1.调用collection的toArray方法,但是因为collection是接口,其实就是相当于调用传递进来的参数的toArray方法,toArray方法的目的返回包含此集合中所有元素的数组。
如果此集合保证其迭代器返回元素的顺序,则此方法必须以相同的顺序返回元素。
返回的数组将是“安全的”,因为这个集合不维护对它的引用。(换句话说,这个方法必须分配一个新的数组,即使这个集合由一个数组支持)。因此,调用者可以自由地修改返回的数组。
此方法充当基于数组和基于集合之间的桥梁
2.然后集合容器转换为数组之后,再赋值给elementData
3.将elemendata的长度赋值给size,再把size属性进行判断
4. c.toArray 被重写可能返回的有可能不返回一个 Object 数组,所以需要进行类型匹配判断
例如:
String.class 是能对类名的引用取得在内存中该类型class对象的引用,而new String().getClass() 是通过实例对象取得在内存中该实际类型class对象的引用
5.如果类型不一致,调用Arrays.copyof进行复制操作,底层调用本地方法system.copyof
,然后返回一个泛型数组,再将这个泛型数组赋值给elementData,即地址赋值,注意这里的elementdata属性不是私有的,也不是常量
6.如果类型一致,直接将elemendata赋值给EMPTY_ELEMENTDATA;
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
/**
* 1.将这个<tt>ArrayList</tt>实例的容量调整为列表的当前大小。应用程序可以使用这个操作来最小化<tt>ArrayList</tt>实例的存储。
Mount是AbstractList中的,由迭代器和列表迭代器使用,目的是为了防止属性意外的改变. 如果这个字段的值意外变化,迭代器(或列表迭代器)将抛出一个{@code ConcurrentModificationException}来响应{@code next}, {@code remove}, {@code previous},提供了快速的故障行为,而不是在迭代期间面对并发修改时的非确定性行为。
2.判断size和缓冲长度的大小,如果size小于缓冲数组的长度,再判断size是否等于0,如果size等于0,则返回EMPTY_ELEMENTDATA,否则就用Arrays.copyof对elementada进行自我复制,新的elementdata的长度为实际有效个数size
*/
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
/**
*如果需要,增加这个<tt>ArrayList</tt>实例的容量,以确保它至少可以容纳最小容量参数指定的元素数量。 *
* @param minCapacity 描绘期望的最小容量
1.先定义一个最小期望
2.判断elementdata是否等于默认大小的空实例的共享空数组实例
3.如果等于,则返回0给最小期望,如果不等于,则返回10给最小期望
4.再判断传递进来的形参和最小期望的关系
5.如果形参大于最小期望,调用ensureExplicitCapacity方法,此时把接收的minCapacity继续当作形参传给ensureExplicitCapacity
*/
public void 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);
}
}
//定义私有的静态方法calculateCapacity,计算出实际长度,该方法形参为elementData和传入的最小长度,如果传递的elementData地址等于默认共享数组的地址,返回传入最小长度和10之中的最大值,如果地址不等,返回传入的最小长度
private static int calculateCapacity(Object[] elementData, int minCapacity) {