ArrayList是一种可以动态增长和所见的索引序列。其实现是基于动态对象数组,因此,其中的元素之间的物理存储是连续的,因此,元素的随机访问效率很高,然而对其中间的元素进行插入和删除的操作效率较低,因为需要移动其它元素。
Vector和ArrayList的API基本相同,区别在于ArrayList是非线程安全的,而Vector是线程安全的,且Vector的效率低于ArrayList。因此在不考虑多线程并发的时候,应当使用ArrayList。
Linkedlist是一种可以在任何位置进行高效地插入和删除操作的有序序列。其实现的数据结构为链表,因此对其中的元素进行随机访问的效率较低,而进行插入和删除操作的效率较高。
ArrayList的扩容机制:
首先,查看ArrayList的add方法的源码实现:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 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);
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);
}
ArrayList的默认初始大小为10,由源码30行可看出,扩容时策略是以旧容量的1.5倍扩容。
Vector的扩容机制:
Vector类的grow方法:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
由源码看出,Vector的扩容策略是以旧容量的2倍扩容。
LinkedList的扩容机制:
public boolean add(E e) {
linkLast(e);
return true;
}
/**
* Links e as last element.
*/
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
不难看出,LinkedList中定义了一个名为Node的内部类,在执行add操作的时候会new出来一个Node对象,追加到链表的尾部。