1. 创建ArrayList
ArrayList<Object> list1 = new ArrayList<>();
ArrayList<Object> list2 = new ArrayList<>(16);
ArrayList<Object> list3 = new ArrayList<>(list2);
ArrayList为我们提供了三个构造方法。我们创建ArrayList对象除了使用空参构造,还可以传递一个int数值指定初始容量或者传递一个集合。
1.1 空参构造ArrayList()
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
空参构造非常简单,将DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值给elementData ,会为我们创建一个空的集合。DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个用static final修饰的空数组。
* 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.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
elementData是一个Object数组,定义在类的成员变量,用来存放实际数据。源码如下:
/**
* 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
注意elementData使用transient修饰。表明在采用Java默认的序列化机制的时候,被该关键字修饰的属性不会被序列化。而ArrayList类实现了java.io.Serializable接口,即采用了Java默认的序列化机制。但是elementData在网络传输的时候不序列化肯定是不行的,翻看源码会发现ArrayList自己实现了序列化和反序列化的方法,具体可以见6.3小节。
DEFAULTCAPACITY_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.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
注意DEFAULTCAPACITY_EMPTY_ELEMENTDATA类型为static final,表明其在内存中只有一份且禁止修改。
空参构造底层为我们创建的是一个空的数组,初始容量是0,这肯定没法存东西的,那么当我们调用add()方法往集合添加元素时到底发生了什么?我们在第二小节见分晓。
1.2 初始化指定集合大小ArrayList(int initialCapacity)
我们可以在创建ArrayList集合的时候指定其处理容量,看下源码:
/**
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
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);
}
}
逻辑非常简单,如果初始容量>0,则创建一个该大小的数组。如果容量为0,则创建一个空数组。如果容量<0,抛出异常。
这里抛一个问题:为什么《阿里巴巴Java开发手册》里面建议初始化集合时尽量显示的指定集合大小?答案同样在第二小节揭晓。
1.3 初始化传递集合ArrayList(Collection<? extends E> c)
*
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
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 wit