JAVA集合之ArrayList - PART II

37 阅读1分钟

我们来看下add方法(java 11及之后版本):

 private void add(E e, Object[] elementData, int s) {
        if (s == elementData.length) {
            elementData = this.grow();
        }

        elementData[s] = e;
        this.size = s + 1;
    }

    public boolean add(E e) {
        ++this.modCount;
        this.add(e, this.elementData, this.size);
        return true;
    }

    public void add(int index, E element) {
        this.rangeCheckForAdd(index);
        ++this.modCount;
        int s;
        Object[] elementData;
        if ((s = this.size) == (elementData = this.elementData).length) {
            elementData = this.grow();
        }

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

因为一开始数组的默认长度是0,调用add方法时会调用grow方法。

 private Object[] grow(int minCapacity) {
        int oldCapacity = this.elementData.length;
        if (oldCapacity <= 0 && this.elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return this.elementData = new Object[Math.max(10, minCapacity)];
        } else {
            int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, oldCapacity >> 1);
            return this.elementData = Arrays.copyOf(this.elementData, newCapacity);
        }
    }

    private Object[] grow() {
        return this.grow(this.size + 1);
    }

可见第一次调用add时数组会将长度从0扩展到10。当ArrayList中的元素个数超过数组的容量时,就会创建一个新的数组,容量为原来的1.5倍,然后通过Arrays.copyOf方法把原来数组中的元素复制到新数组中。

这里提一下grow方法中的位运算oldCapacity >> 1——按位右移一位。它等同于除以2。

例:1000(8) 0100(4) 0010(2)