参考文章:JCFInternals
JDK:1.9

介绍:
ArrayList实现了List接口,是顺序容器,即元素存放的数据与放进去的顺序相同,允许放入null元素,底层通过数组实现,未实现同步。

实现功能:

  • size():得到当前集合元素个数
  • isEmpty():判断集合是否为空
  • get(int index):获得指定位置集合
  • set(int index, T element):将指定位置集合设置为指定值
  • add(T element):向集合添加一个元素
  • add(int index, T element):向集合指定下标添加指定元素
  • remove(int index):移除指定下标的元素
  • remove(Object o):移除集合中第一次出现的指定元素

代码

import java.util.*;

public class MyArrayList<T> {

    Object[] elementData;
    private int size;
    public static final int DEFAULT_CAPACITY = 10;

    public static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE;

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    // 初始化elementData
    MyArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    // 下标越界检查
    private boolean rangeCheck(int index) {
        if (index < 0 || index > size) {
            throw new RuntimeException("下标越界!");
        }
        return true;
    }

    // 扩容
    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 = (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
        }
        // 扩容
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return 0 == size;
    }

    public T get(int index) {
        // 下标越界检查
        rangeCheck(index);
        return (T) elementData[index];
    }

    public T set(int index, T element) {
        // 下标越界检查
        rangeCheck(index);
        // 取到将要被覆盖的值
        T oldElement = (T) elementData[index];
        // 指定位置赋值
        elementData[index] = element;
        // 返回被覆盖的值
        return oldElement;
    }

    public void add(T element) {
        // 检查容量
        if (size == elementData.length) {
            // 满了就扩容
            grow(size + 1);
        }
        add(size, element);
    }

    public void add(int index, T element) {
        // 下标越界检查
        rangeCheck(index);
        // 检查容量
        if (size == elementData.length) {
            // 满了就扩容
            grow(size + 1);
        }
        System.arraycopy(elementData, index, elementData, index + 1, size - index);
        elementData[index] = element;
        size++;
    }

    public T remove(int index) {
        // 下标越界检查
        rangeCheck(index);
        T oldElement = (T) elementData[index];
        int numMoved = size - index - 1;
        if (numMoved > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        }
        elementData[--size] = null;
        return oldElement;
    }

    private void fastRemove(int index) {
        int numMoved = size - index - 1;
        if (numMoved > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        }
        elementData[--size] = null;
    }

    public boolean remove(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++) {
                if (elementData[i] == null) {
                    fastRemove(i);
                    return true;
                }
            }
        } else {
            for (int i = 0; i < size; i++) {
                if (elementData[i].equals(o)) {
                    fastRemove(i);
                    return true;
                }
            }
        }
        return false;
    }
}