操作
public static void main(String[] args) {
List<Integer> arrayList=new ArrayList<>();
//添加
arrayList.add(1);
//获取
arrayList.get(0);
//移除
arrayList.remove(0);
//是否包含
arrayList.contains(1);
}
成员变量
private int size; // 实际元素个数
transient Object[] elementData; //存储的数据空间,有可能不满
注意:上面的 size 是指 elementData 中实际有多少个元素,而 elementData.length 为集合容量,表示最多可以容纳多少个元素。
默认初始化大小为10
private static final int DEFAULT_CAPACITY = 10;
添加
计算当前的存储空间是不是大于10,如果大于则扩大,如果不大于则不进行操作。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
扩容
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
由此可知:每次扩容扩大 1/2。
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自己实现了序列化和反序列化,因为它实现了writeObject和readObject方法。
- ArrayList基于数组实现,会自动扩容。
- 添加元素时会自己判断是否需要扩容,最好指定一个大概的大小,防止后面多次扩容带来的内存消耗;删除元素时不会减少容量,删除元素时,将删除掉的位置元素置为null,下次gc就会自动回收这些元素所占的空间。
- ArrayList是线程不安全的。
- 使用iterator遍历可能会引发多线程异常。