Welcome To Heike07's Blog.

欢迎来到Heike07官方博客

ArrayList源码解析

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{}

ArrayList<E>类继承了AbstractList<E>抽象类, 实现了List<E>接口, RandomAccess接口, Cloneable接口, java.io.Serializable接口.

    AbstractList<E>抽象类: 此类提供 List 接口的骨干实现,从而最大限度地减少了实现由“随机访问”数据存储(如数组)支持的接口所需的工作.
    List<E>接口:  List是个集合接口,只要是集合类接口都会有个“迭代器”( Iterator ),利用这个迭代器,就可以对list内存的一组对象进行操作.
    RandomAccess接口: RandomAccess是一个标记接口,实现该接口表示支持快速访问.
    Cloneable接口: Cloneable接口声明中没有指定要实现的方法,一个类要实现Cloneable,最好是覆盖Object类的clone()方法.
    Serializable接口: Serializable接口是启用其序列化功能的接口.
ArrayList类中的属性(Property):
private static final long serialVersionUID = 8683452581122892189L;
    ↑ serialVersionUID静态常量的作用是 序列化时保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性.
private static final int DEFAULT_CAPACITY = 10;

↑ DEFAULT_CAPACITY静态常量的作用是   保证ArrayList类默认容量 也就是 10.

private static final Object[] EMPTY_ELEMENTDATA = {};

↑ 当调用构造方法参数为0时,默认设置个空数组.

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

↑ 当调用无参构造方法时, 默认设置空数组.(和使用0作为参数的返回空数组对象不同)

transient Object[] elementData;

↑ 此数组引用为真正保存数据的引用. transient关键字,用来表示一个域不是该对象串行化的一部分.当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的.

private int size;

↑ size变量用于保存ArrayList对象中的实际元素个数.

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

↑ 设置数组的最大容量..

构造方法( Constructor Method):
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
    }
}

↑ 构造方法传入默认的capacity. 当initialCapacity大于0时, 设置指定大小的Object数组, 等于0时, 设置一个空数组EMPTY_ELEMENTDATA, 否则抛出IllegalArgumentException异常.

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

↑ 无参构造方法, 默认设置一个Object空数组 DEFAULTCAPACITY_EMPTY_ELEMENTDATA.

public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

↑ 参数为一个Collection对象的构造方法. 将Collection对象里面的值copy到ArrayList对象中, 若Collection对象中没有值,那么ArrayList对象设置一个空数组.

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

↑ add方法向ArrayList对象末尾中添加数据.每添加一个数据 size的值加1.

public void add(int index, E element) {
    rangeCheckForAdd(index);

    ensureCapacityInternal(size + 1);
    System.arraycopy(elementData, index, elementData, index + 1,size - index);
    elementData[index] = element;
    size++;
}

↑ add方法向ArrayList对象中指定索引添加数据.每添加一个数据 size的值加1.

private void rangeCheckForAdd(int index) {
    if (index > size || index < 0)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

↑ rangeCheckForAdd()方法用于判断索引是否越界.如果越界则抛出IndexOutOfBoundsException异常

两个add方法都使用了ensureCapacityInternal()方法.
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

private void grow(int minCapacity) {

    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
   
    elementData = Arrays.copyOf(elementData, newCapacity);
}
ensureCapacityInternal()方法判断数组引用是否为一个空数组. 如果为空数组则调用ensureExplicitCapacity()方法判断值得可行性,由ensureExplicitCapacity()方法调用grow()方法为数组动态的分配空间.
    分配过程:
            ①获取数组的先有容量.
            ②将原数组大小值扩大到1.5倍得到一个新的值.
            ③判断新的值是否比指定的值(minCapacity)小,若果小于指定的值,那么新的值就是minCapacity.
            ④判断新的值是否大于数组的最大值.
            ⑤调用Array.copyOf()方法返回一个存有原数组对象elementData的数据而数组大小为newCapacity的新的数组并赋值给elementData.
点赞

发表回复