ArrayList源码分析

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

 Serializable

这是源码里面的实现了这个接口我们就可以进行序列话和反序列化了

Cloneable

这是源码里面的实现了这个接口可以复制对象了复写clone方法,他本地有一个接口就可以有一个本地方法调用native方法可以克隆

深克隆:克隆对象里面的对象的引用为新的引用

浅克隆:克隆对象里面的对象的引用为新的引用老的引用

RandomAccess

这是源码里面的实现了这个接口理解为

使用fori循环遍历比迭代器遍历快

会判断走那种遍历

indexedBinarySerach(list,key)或iteratorBinarySerach(list,key)方法

添加方法add(E e)

List<String> list = new ArrayList<>();

这个的时候会创建一个新的空数组

    public boolean add(E e) {
        // 判断是否需要扩容
        ensureCapacityInternal(size + 1);
        // 将新元素追加到相应的数组中
        elementData[size++] = e;
        return true;
    }

第一次添加调用调用初始化长度和扩容

    // minCapacity = size + 1
    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        // 如果当前数组为空,则所需容量就是默认容量
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

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

        // 增加元素所需空间不足,则需扩容
        if (minCapacity - elementData.length > 0)
            // 真正的扩容方法
            grow(minCapacity);
    }

扩容

    // 数组默认的最大长度
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    private void grow(int minCapacity) {
        // 旧数组的长度
        int oldCapacity = elementData.length;
        // 扩容为原来的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        // 判断新的数组容量是否达到需求
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        // 判断新容量是否溢出
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // 调用Arrays.copyOf()方法,将elementData数组复制到一个新数组
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0)
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    }

添加方法add(index i ,E e)

这个方法也是很简单的大概是需要判断是否扩容

然后把索引位置的数组拷贝到后面

比如说我们需要把索引为1的数据改为4

addAll

差不多的

get

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

    /**
     * Returns the element at the specified position in this list.
     *
     * @param  index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

很简单第一个方法判断是否越界,第二个直接通过索引获得

原文地址:https://www.cnblogs.com/xiaoruirui/p/15138393.html