Open Source, Open Future!
  menu
107 文章
ღゝ◡╹)ノ❤️

ArrayList

简介

基于数组的有序可重复的集合。

类图

image.png

主要字段

// 列表中的数据储存在这里
transient Object[] elementData; 
// 实际存储数据的大小(不是列表的容量)
private int size;

image.png

常量

// 默认大小
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

构造函数

// 创建一个空列表,大小为 0
ArrayList()
// 创建一个指定大小的列表
ArrayList(int capacity)
// 将指定的集合拷贝给列表
ArrayList(Collection<? extends E> collection)

部分API说明

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_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 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);
    }

流程说明:

  1. 先确保集合能容下新元素;
    1.1. 若为空集合,则将会在后面将集合扩容到10
    1.2. 变量modCount1(用于记录集合被修改的次数)
    1.3. 若集合足以容下新元素,直接返回;否则进行下一步扩容;
    1.4. 创建一个新数组,大小为原来的3/2(不能低于底限minCapacity),并将数据全部拷贝过来;
    1.5. 集合底层关联到新数组;
  2. 存储新元素(即将新元素放入数组elementData中),size1

主要关注remove(int index)方法,源码如下:

    public E remove(int index) {
        // 范围检查
        rangeCheck(index);
        // 变量 modCount 加 1(用于记录集合被修改的次数)
        modCount++;
        // 获取指定索引处的元素
        E oldValue = elementData(index);
        int numMoved = size - index - 1;
        if (numMoved > 0)
            // 指定索引后面的所有元素向前移动一位
            System.arraycopy(elementData, index + 1, elementData, index,
                    numMoved);
        // 最后一位元素置为null
        elementData[--size] = null; // clear to let GC do its work
        // 返回要删除的数据
        return oldValue;
    }

    public E set(int index, E element) {
        // 范围检查
        rangeCheck(index);
        // 获取指定索引处的元素
        E oldValue = elementData(index);
        // 用新值覆盖指定索引处的旧值
        elementData[index] = element;
        // 返回旧值
        return oldValue;
    }

    public E get(int index) {
        rangeCheck(index);
        return elementData(index);
    }

    E elementData(int index) {
        return (E) elementData[index];
    }

排序

示例

测试

备注

使用JDK版本为1.8