ArrayList
构造函数
public ArrayList(int initialCapacity) //创建指定容量的数组
public ArrayList() //直接使用默认的空数组
public ArrayList(Collection<? extends E> c) //将集合转换成数组后作为list的初始值
ArrayList的默认初始容量为10,当添加元素时,会计算所需要的最小容量,如果最小容量大于容器当前的容量时,则以当前容器容量的1.5倍扩大容器
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);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
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);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
removeAll删除指定集合中的元素,retainAll删除不在指定集合中的元素
Java中的处理方式为找出需要保留的元素
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
public boolean removeAll(Collection<?> c) {
return batchRemove(c, false);
}
public boolean retainAll(Collection<?> c) {
return batchRemove(c, true);
}
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
根据容器中当前元素的个数设置容器的容量
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size);
}
}
利用内部类创建了一个Iterator接口的实现类(Itr),利用Itr的对象可以实现对数组的遍历而外部不必知道ArrayList内部数据的结构
涉及的设计模式:迭代模式
for遍历时不能删除元素,可以使用iterator遍历时删除
为了减少ArrayList频繁扩容导致的性能问题,建议使用ensureCapacity(int minCapacity)一次性设置容器的容量