ArrayList add remove 代码分析

Add

首次add 元素需要对数组进行扩容(初始化Capacity 10, 第二次扩容10>>1 为5, 第三次扩容15>>1 为7), 每次扩容之前长度的1.5倍,当add 的数据较多时扩容较为频繁,这时建议在new ArrayList() 指定初始容量 或者 使用 linkedList

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

// 确定内存容量
 private void ensureCapacityInternal(int minCapacity) { //minCapacity=1 增加的容量
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // DEFAULTCAPACITY_EMPTY_ELEMENTDATA=10 //默认的容量
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

// 明确容量
        ensureExplicitCapacity(minCapacity); // minCapacity=10
    }

/**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     * 确保数组中的容量能存储的下新增的容量,不足则扩容
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity)  { //minCapacity=10
        // overflow-conscious code
        int oldCapacity = elementData.length;  //oldCapacity =0
        int newCapacity = oldCapacity + (oldCapacity >> 1); //newCapacity =0
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;  //newCapacity =10
        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 对原数组进行扩容
    }

 

remove
除非是当前数组中只剩下一个元素,否则每次remove 都会 System.arraycopy 移动元素。
如果是remove(obj) 需要每次遍历数组找到equals的对象,然后 System.arraycopy 移动元素。

LinkedList 虽然不用移位,但也每次都要变量链表,更改引用对象
  public E remove(int index) {
        rangeCheck(index); // 校验要删除的索引是否超出范围

        modCount++;// 操作count++
        E oldValue = elementData(index);// 取出要删除的元素

        int numMoved = size - index - 1; // 得出要移动元素个数
        if (numMoved > 0)
// 移动元素
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
// 将删除的元素置为null
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

get
 E elementData(int index) {
// 直接根据索引获取元素
        return (E) elementData[index];
    }

 

posted @ 2019-05-04 22:23  卖臭豆腐喽  阅读(287)  评论(0编辑  收藏  举报