ArrayList解析
- 继承的类和实现的接口
- 构造方法
继承的类和实现的接口
public class ArrayList<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, Serializable
List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。(此类大致上等同于 Vector 类,但此类是线程不安全的而vector是线程安全的。)
每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单。
扩容公式:新容量 = 旧容量/2 + 旧容量(底层是通过移位操作,右移一位相当于除以2)
构造方法
ArrayList(): 这里初始容量为 0,可能有人说是10,但别急,详细可下面源码
ArrayList(Collection<? extends E> c) :构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection
的迭代器返回它们的顺序排列的。
ArrayList(int initialCapacity) :构造一个具有指定初始容量的空列表。
源码
首先,定义一个elementData数组,用来存储ArrayList中的元素,从这个可以看出,ArrayList是底层是借组于数组来实现的。
transient Object[] elementData; // non-private to simplify nested class access
构造方法
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);
}
}
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray(); //将容器collection转化为数组
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;
}
}
另外一个就是这里
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; 就是这里,这是一个数组名,它的定义如下
}
它的数组是空的!
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
郁闷许久,来回看了几次后,发现关于 transient Object[] 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是一个存储ArrayList元素的数组缓冲区,ArrayList的容量是此数组缓冲区的长度,在添加第一个元素时,将自动扩展为DEFAULT_CAPACITY,而DEFAULT_CAPACITY的申明是:
private static final int DEFAULT_CAPACITY = 10;
再看一个add方法
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 添加一个元素时,调用函数
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//构造方法中已经初始化了,所以他们两个相等
return Math.max(DEFAULT_CAPACITY, minCapacity); //返回10
}
return minCapacity;
}
因此,我觉得是在加入第一个元素后,容量才为10的,当然,这只是我的看法,我也无法保证一定是对的,如果哪位道友,觉得理解有误的话,可以指出来,虚心学习,共同进步~