本文章基于jdk1.8_171
ArrayList介绍
java中用的最多(个人感觉)的一个集合,内部维护着一个数组,方便,不用像数组一样事先给定大小。
成员变量
private static final int DEFAULT_CAPACTIY = 10;
默认容量,如果新建一个对象时没有指定容量,会新建一个空数组,并在第一次添加元素的时候把容量改为10(DEFAULT_CAPACTIY
),当然,前提是添加元素的个数不大于10个。
private static final Object[] EMPTY_ELEMENTDATA = {};
一个空数组。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
也是一个空数组,新建对象时如果没有指定容量,就把这个数组作为内部的数组。与EMPTY_ELEMENTDATA
的区别是,第一次添加元素时,如果数组是DEFAULTCAPACITY_EMPTY_ELEMENTDATA
,容量就变为DEFAULT_CAPACTIY
。(添加元素不超过10个)。
transient Object [] elementData;
集合里真正放数据的地方, 这个数组的长度就是集合的容量。
private int size;
集合里实际的元素个数,不是数组长度。
构造器
public ArrayList(){
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
无参构造器,把DEFAULTCAPACITY_EMPTY_ELEMENTDATA
作为内部数据,添加第一个元素时容量增长为DEFAULT_CAPACTIY
。
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);
}
}
新建一个容量为initialCapacity
的对象,initialCapacity
小于0时抛出异常。
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;
}
}
新建一个对象,并把集合c的数组赋予elementData
,如果集合c为空,elementData = EMPTY_ELEMENTDATA
。注意,此时数组长度就是size。
方法
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
常用方法,向集合内添加一个元素。先看容量够不够添加元素,不够就扩容。然后在末尾添加元素,size+1。
private void calculateCapacity(Object[] elementDate,int minCapacity){
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementDate,minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
这三个放在一起说,表示扩容前的检查。如果内部数组是DEFAULTCAPACITY_EMPTY_ELEMENTDATA
并且需要的最小容量不大于
DEFAULT_CAPACITY
,那么就把容量定成DEFAULT_CAPACITY
。最后如果需要的容量大于内部数组长度,则进行扩容。注意:modCount表示此集合被修改的次数,这个变量定义在父类AbstractList
中。
未完待续。。。