综合来说,在需要频繁读取集合中的元素时,更推荐使用ArrayList,而在插入和删除操作较多时,更推荐使用LinkedList。
默认的初始化容量为10,当元素数量超过数组容量时会触发扩容,每次扩容,容量会变成原数组的1.5倍,然后将原数组的内容拷贝到新数组中,完成扩容操作。
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth 一般是1*/
oldCapacity >> 1 /* preferred growth */);//old右移一位即除以2
return elementData = Arrays.copyOf(elementData, newCapacity);//newCapacity是old的1.5倍
} else {
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
//如果是DEFAULTCAPACITY_EMPTY_ELEMENTDATA(初始化未指定容量),第一次扩容为DEFAULT_CAPACITY(10)
}
}
private Object[] grow() {
return grow(size + 1);
}
如果创建空的 ArrayList 和 Vector即不指定 initialCapacity 大小,它的底层数组其实是空的,没有申请空间,当第一次向 ArrayList 集合中添加元素时,底层数组扩容到10.
当使用带参的构造方法,会直接申请参数大小的容量。
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);
}
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
ArrayList 和 Vector 类封装了一个动态的, 允许再分配的 Object[] 数组. 如果一开始就知道 ArrayList 和 Vector 需要保存多少个元素, 则可以在创建它们时就指定 initialCapacity 大小,可以减少需要频繁扩容消耗的时间.
ArrayList和Vector在很多时候都很类似。
以下是ArrayList和Vector的不同点。
List<Integer> objects = Collections.synchronizedList(new ArrayList<Integer>());
------------------------------------------------------------------------------------
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list) :
new SynchronizedList<>(list));
}
------------------------------------------------------------------------------------
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {//扩展了功能,让不支持同步的List类有了有了同步方法,装饰者模式
@java.io.Serial
private static final long serialVersionUID = -7754090372962971524L;
@SuppressWarnings("serial") // Conditionally serializable
final List<E> list;
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
SynchronizedList(List<E> list, Object mutex) {
super(list, mutex);
this.list = list;
}
//举例方法
public E set(int index, E element) {
synchronized (mutex) {return list.set(index, element);}
}
}
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
public Vector() {
this(10);
}
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth 一般是1*/
capacityIncrement > 0 ? capacityIncrement : oldCapacity
/* preferred growth */);
return elementData = Arrays.copyOf(elementData, newCapacity);
//capacityIncrement 在构造方法中指定
}
private Object[] grow() {
return grow(elementCount + 1);
}