Java数据结构

我爱读源码--ArrayList

2018-12-19  本文已影响0人  衤刀学者

ArrayList

//* 含参数
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        //创建新的object数组
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {]
        //用默认的空数组
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        //非法的容量
        throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
    }
}
// * 不含参数
public ArrayList() {
    //构造默认容量的数组
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public void trimToSize() {
    modCount++;
    if (size < elementData.length) {
        elementData = (size == 0)
          ? EMPTY_ELEMENTDATA
          : Arrays.copyOf(elementData, size);
    }
}
public E get(int index) {
    //判断是否角标越界,越界IndexOutOfBoundsException
    rangeCheck(index);

    return elementData(index);
}
 public E set(int index, E element) {
    rangeCheck(index);

    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}
public boolean add(E e) {
    //先让数组扩容
    ensureCapacityInternal(size + 1); 
    //最后一个元素是新元素
    elementData[size++] = e;
    return true;
}
public void add(int index, E element) {
//先检查越界
    rangeCheckForAdd(index);
//容量增加1
    ensureCapacityInternal(size + 1); 
//添加元素相对慢的原因所在
//复制数组,新元素索引之后的元素都复制到新数组
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}
public E remove(int index) {
//先检查越界
    rangeCheck(index);
//此列表被结构修改的次数。
//在使用迭代器遍历的时候,用来检查列表中的元素是否发生结构性变化(列表元素//数量发生改变)了,
//主要在多线程环境下需要使用,防止一个线程正在迭代遍历,
//另一个线程修改了这个列表的结构。
//好好认识下这个异常:ConcurrentModificationException。
//ArrayList是非线程安全的。

    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;
}
    private void fastRemove(int index) {
    //修改次数+1
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        // clear to let GC do its work                     
        elementData[--size] = null; 
    }
public void clear() {
    modCount++;

    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}
private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
//当集合A的大小改变的时候返回的是True,大小没有改变的时候返回的是False。
public boolean retainAll(Collection<?> c) {
    Objects.requireNonNull(c);
    return batchRemove(c, true);
}

对于list的删除操作,建议看这个文章
传送门


对于新增和删除操作add和remove索引之后的所有元素,ArrayList要移动数据,所以效率相对较低

上一篇下一篇

猜你喜欢

热点阅读