ArrayList源码学习

容器初始化方法:

两种初始化方法

  1. 不指定初始容器大小
ArrayList arrayList = new ArrayList();

内部源码操作

public ArrayList() {
       super();
       this.elementData = EMPTY_ELEMENTDATA;
   }
EMPTY_ELEMENTDATA 是一个空的Object类型的数组
private static final Object[] EMPTY_ELEMENTDATA = {};
  1. 指定初始化容器大小
ArrayList arrayList = new ArrayList(2);
//如果是指定初始化大小,内部会把this.elementData = new Object[initialCapacity];这个参数初始化一个大小

添加方法

有4种添加方法:add(E e),add(int index,E e),addAll(Collection c),addAll(int index , Collection c);
add(E e)方法源码:

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 保证容器长度
        elementData[size++] = e; //把添加的元素放到最后,这个size会记录当前添加的时第几个,然后下一个是在哪个位置
        return true;
    }

 private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//如果容器没有指定初始化大小,则初始化一个最小的,jdk1.7里面指定的最小的大小是10
        }

        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);  //内部使用了System.arraycopy复制数组
    }


add(int index ,E e )源码:

public void add(int index, E element) {
        rangeCheckForAdd(index);//检查是否越界

        ensureCapacityInternal(size + 1);  // 先扩容,保证后面复制的时候需要的长度
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index); //主要是这里调用了api复制数组,移动index位置到后面一个位置,留出位置放
        elementData[index] = element;放数据
        size++;//保证记录的size是下次需要记录的最后的位置
    }

addAll(Collection c)源码:

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;
    }
跟add(int index,E e)差不多

addAll(int index, Collection c)源码:

 public boolean addAll(int index, Collection c) {
        rangeCheckForAdd(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount

        int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);

        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }

删除方法

remove(int index),remove(Object obj),removeAll(Collection c)
reomve(Object obj)方法源码:

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

private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // 差不多,也是使用arrayCooy方法   根据下标移除也差不多,removeAll也差不多
    }

获取方法

get(int index):直接数组下标取值

你可能感兴趣的:(ArrayList源码学习)