ArrayList源码分析

ArrayList源码分析

基于数组实现,支持自动扩容

image.png
  • RandomAccess是一个标记接口,表示支持快速的随机访问
  • Serializable 序列化接口,支持序列化功能
  • Cloneanble 表示支持克隆

属性

image.png

elementData:表示存储元素数组
size:数组大小

构造方法

ArrayList(int initialCapacity)
ArrayList()
ArrayList(Collection c) 

#ArrayList(int initialCapacity)

public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        // 初始容量大于0,创建数组
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        // 初始容量小玉0,构造空数组
        // private static final Object[] EMPTY_ELEMENTDATA = {};
        this.elementData = EMPTY_ELEMENTDATA 构造;
    } else {
        // 初始容量小于0,直接抛出异常
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

#ArrayList()

public ArrayList() {
    // 空参构造
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(Collection c) {
    // 将传入集合转换成数组
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            // 集合元素不是object数组,创建新的数组
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

添加单个元素

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

 private void ensureExplicitCapacity(int minCapacity) {
     // 记录修改的次数
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            // 容量不够进行扩容
            grow(minCapacity);
    }

指定位置添加元素

public void add(int index, E element) {
    // 校验位置是否在元素内
    rangeCheckForAdd(index);
    // 增加元素修改次数
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    // 将index+1元素往后移动
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    // 添加element
    elementData[index] = element;
    // 数组大小加一
    size++;
}

数组扩容

private void grow(int minCapacity) {
    // 数组长度
    int oldCapacity = elementData.length;
    // 新容量是之前的1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    //     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    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;
    }

添加多个元素

public boolean addAll(Collection c) {
    // 转换成数组
    Object[] a = c.toArray();
    int numNew = a.length;
    // 增加修改次数与确保容量够用
    ensureCapacityInternal(size + numNew);  // Increments modCount
    // 拷贝数组
    System.arraycopy(a, 0, elementData, size, numNew);
    // 增加数组长度
    size += numNew;
    return numNew != 0;
}

移出单个元素

public E remove(int index) {
    // 判断位置是否在数组长度内
    rangeCheck(index);
    // 增加修改次数
    modCount++;
    // 记录该位置的原值
    E oldValue = elementData(index);
    // 锁定要移动的长度
    int numMoved = size - index - 1;
    if (numMoved > 0)
        // 数组拷贝
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    // 数组大小减一,gc工作
    elementData[--size] = null; 
    // 返回旧值
    return oldValue;
}

移出多个元素

 public boolean removeAll(Collection c) {
        // 判断非空
        Objects.requireNonNull(c);
        return batchRemove(c, false);
    }
 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 {
            // 兼容AbstractCollection
            if (r != size) {
                System.arraycopy(elementData, r,
                                 elementData, w,
                                 size - r);
                w += size - r;
            }
            if (w != size) {
                // 帮助gc
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                // 元素修改次数
                modCount += size - w;
                // 数组大小变动
                size = w;
                modified = true;
            }
        }
        return modified;
    }

查找单个元素

public int indexOf(Object o) {
    // 元素为null 情况
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
     // 元素不为null的情况
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    // 找不到返回-1
    return -1;
}

转换成数组

public Object[] toArray() {
    return Arrays.copyOf(elementData, size);
}

转换成数组,指定类型

public  T[] toArray(T[] a) {
    if (a.length < size)
        // 传入数组小于原来数组大小,直接复制新数组返回
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
    // 将原来数组复制到a中
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        // 传入数组大小大于size,赋值为null
        a[size] = null;
    return a;
}

你可能感兴趣的:(ArrayList源码分析)