美文网首页
ArrayList源码解析

ArrayList源码解析

作者: IT_lz | 来源:发表于2019-05-31 16:21 被阅读0次

1、构造方法初始化

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);
    }
}
  • ArrayList底层由数组构成,如果用户未指定数组大小,则赋值为默认的数组EMPTY_ELEMENTDATA(这是一个空数组,在添加第一个元素时,会扩容为DEFAULT_CAPACITY = 10 大小的数组)。
  • 用户指定大小后,将按照指定大小创建数组。

2、Add方法

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
  • List接口下的集合是可以允许加入重复的元素,所以add方法永远返回true。

  • ensureCapacityInternal(int x)检测加入元素之后的大小是否超出目前的长度, 如果超过则扩容。

    扩容机制 :

    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);
    }
    
扩容流程.png
  • Arrays.copyOf(elementData, newCapacity);

​ 第二个变量为新数组的长度,如果新数组长度超过老数组长度,则多出来的元素为默认值。

  • 最后向扩容后的数组中添加元素。到此添加工作已完成。

3、remove()移除元素

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);
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}
  1. 获取当前要返回的值,用于返回。
  2. 将移除的目标元素后面的元素向前平移对齐。
  3. 将最后一个元素置null。在GC时回收掉。
  • System.arraycopy与Arrays.copyOf区别
    1. System.arraycopy操作已有数组。
    2. Arrays.copyOf拷贝之后会生成新的数组。

4、get()获取某个位置的值

public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}
  1. 检查index是否越界,越界则报"IndexOutOfBoundsException"。
  2. 返回数据结果。

相关文章

网友评论

      本文标题:ArrayList源码解析

      本文链接:https://www.haomeiwen.com/subject/xdrgtctx.html