public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
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,就使用默认的数组长度,即为10
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;
}
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
从这段源码中可以看出e允许为null,即ArrayList允许添加进值为null的元素
通过以下代码来测试,以验证上述特性
public class Test {
public static void main(String[] args){
ArrayList arrayList = new ArrayList();
arrayList.add(null);
System.out.println(arrayList.get(0));
}
}
从上面的源码可看出add()中调用了ensureCapacityInternal(int minCapacity),现继续往下跟踪探究
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
minCapacity为当前ArrayList的长度,在ensureCapacityInternal()中可以看出minCapacity总是大于或者等于默认长度
再往下跟踪ensureExplicitCapacity(int minCapacity)
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
其中的重头戏在于grow(int minCapacity),继续往下跟踪
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
再通过copyOf()继续往下跟踪
public static T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
public static T[] copyOf(U[] original, int newLength, Class extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
这个add()是对指定的位置插入元素,先看相应的源码
public void add(int index, E element) {
rangeCheckForAdd(index);//对index的合法性进行判断
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
ArrayList通过不同的构造方法可以选择3种中其中的一种形式创建,第一种是不带参,创建默认长度为10的属猪;第二种是可以自定义数组的长度;第三种是传入一个Conllection类型的参数。
ArrayList在add()时判断是否需要扩容,如果需要扩容则扩为原来的1.5倍,底层是依次调用copyOf()和System.arraycopy()创建一个新长度的数组,然后将旧数组的元素复制到新数组中去