ArrayList

操作

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遍历可能会引发多线程异常。

文章作者: 凌云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 凌云 !
  目录