ArrayList底层是使用数组实现
private static final Object[] EMPTY_ELEMENTDATA = {};
如果不指定大小,默认为10;
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
动态扩展数组大小原理:
minCapacity:需要的最小数组容量
每次进行扩充时
如果原来的数组的1.5倍大小 < 需要的大小,那么就将数组扩展为需要的大小。否则,扩展为原来的1.5倍大小(留点空间为了更好的插入数据)。
如果需要的大小 > Integer.MAX_VALUE - 8,那么就将数组大小调整为Integer.MAX_VALUE ;由此可见数组大小是可以到达int型的最大值的。
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //oldCapacity * 1.5
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);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
elementData = Arrays.copyOf(elementData, newCapacity);将原来数组的数据复制到新的数组中,调用了Arrays.copyOf().其底层是用System.arraycopy()实现。
public static <T,U> 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;
}
插入操作:
调用系统函数System.arraycopy()将原数组中index开始往后的元素都向后挪动了一位,然后把要插入的元素插入到指定位置。
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
System.arraycopy() :常用作数组的扩容,如ArrayList底层数组的扩容。它是一个静态本地方法,由虚拟机实现,效率自然比用java一个个复制高。为浅复制,对于数组元素是对象,只会复制引用。
* @param src the source array.
* @param srcPos starting position in the source array.
* @param dest the destination array.
* @param destPos starting position in the destination data.
* @param length the number of array elements to be copied.
* @exception IndexOutOfBoundsException if copying would cause
* access of data outside array bounds.
* @exception ArrayStoreException if an element in the <code>src</code>
* array could not be stored into the <code>dest</code> array
* because of a type mismatch.
* @exception NullPointerException if either <code>src</code> or
* <code>dest</code> is <code>null</code>.
*/
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
ArrayList与LinkedList的比较:
LinkedList用链表实现,查询效率低增删效率高。
ArrayList用数组实现, 查询效率高增删效率低。
ArrayList线程不安全。