ArrayList源码解析(2)

2021-01-28 15:24:56 浏览数 (1)

代码语言:javascript复制
/**
 *以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组。
 *返回的数组将是“安全的”,因为该列表不保留对它的引用。 (换句话说,这个方法必须分配一个新的数组)。
 *因此,调用者可以自由地修改返回的数组。 此方法充当基于阵列和基于集合的API之间的桥梁。
 */
public Object[] toArray() {
    return Arrays.copyOf(elementData, size);
}

/**
 * 以正确的顺序返回一个包含此列表中所有元素的数组(从第一个到最后一个元素);
 *返回的数组的运行时类型是指定数组的运行时类型。 如果列表适合指定的数组,则返回其中。
 *否则,将为指定数组的运行时类型和此列表的大小分配一个新数组。
 *如果列表适用于指定的数组,其余空间(即数组的列表数量多于此元素),则紧跟在集合结束后的数组中的元素设置为null 。
 *(这仅在调用者知道列表不包含任何空元素的情况下才能确定列表的长度。)
 */
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
    if (a.length < size)
        // 新建一个运行时类型的数组,但是ArrayList数组的内容
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        //调用System提供的arraycopy()方法实现数组之间的复制
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}

// Positional Access Operations

@SuppressWarnings("unchecked")
E elementData(int index) {
    return (E) elementData[index];
}

/**
 * 返回此列表中指定位置的元素。
 */
public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

/**
 * 用指定的元素替换此列表中指定位置的元素。
 */
public E set(int index, E element) {
    //对index进行界限检查
    rangeCheck(index);

    E oldValue = elementData(index);
    elementData[index] = element;
    //返回原来在这个位置的元素
    return oldValue;
}

/**
 * 将指定的元素追加到此列表的末尾。
 */
public boolean add(E e) {
    ensureCapacityInternal(size   1);  // Increments modCount!!
    //这里看到ArrayList添加元素的实质就相当于为数组赋值
    elementData[size  ] = e;
    return true;
}

/**
 * 在此列表中的指定位置插入指定的元素。
 *先调用 rangeCheckForAdd 对index进行界限检查;然后调用 ensureCapacityInternal 方法保证capacity足够大;
 *再将从index开始之后的所有成员后移一个位置;将element插入index位置;最后size加1。
 */
public void add(int index, E element) {
    rangeCheckForAdd(index);

    ensureCapacityInternal(size   1);  // Increments modCount!!
    //arraycopy()这个实现数组之间复制的方法一定要看一下,下面就用到了arraycopy()方法实现数组自己复制自己
    System.arraycopy(elementData, index, elementData, index   1,
                     size - index);
    elementData[index] = element;
    size  ;
}

/**
 * 删除该列表中指定位置的元素。 将任何后续元素移动到左侧(从其索引中减去一个元素)。
 */
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;
}

/**
 * 从列表中删除指定元素的第一个出现(如果存在)。 如果列表不包含该元素,则它不会更改。
 *返回true,如果此列表包含指定的元素
 */
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 remove method that skips bounds checking and does not
 * return the value removed.
 */
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; // clear to let GC do its work
}

/**
 * 从列表中删除所有元素。
 */
public void clear() {
    modCount  ;

    // 把数组中所有的元素的值设为null
    for (int i = 0; i < size; i  )
        elementData[i] = null;

    size = 0;
}

/**
 * 按指定集合的Iterator返回的顺序将指定集合中的所有元素追加到此列表的末尾。
 */
public boolean addAll(Collection<? extends E> 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;
}

/**
 * 将指定集合中的所有元素插入到此列表中,从指定的位置开始。
 */
public boolean addAll(int index, Collection<? extends E> 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;
}

/**
 * 从此列表中删除所有索引为fromIndex (含)和toIndex之间的元素。
 *将任何后续元素移动到左侧(减少其索引)。
 */
protected void removeRange(int fromIndex, int toIndex) {
    modCount  ;
    int numMoved = size - toIndex;
    System.arraycopy(elementData, toIndex, elementData, fromIndex,
                     numMoved);

    // clear to let GC do its work
    int newSize = size - (toIndex-fromIndex);
    for (int i = newSize; i < size; i  ) {
        elementData[i] = null;
    }
    size = newSize;
}

/**
 * 检查给定的索引是否在范围内。
 */
private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

/**
 * add和addAll使用的rangeCheck的一个版本
 */
private void rangeCheckForAdd(int index) {
    if (index > size || index < 0)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

/**
 * 返回IndexOutOfBoundsException细节信息
 */
private String outOfBoundsMsg(int index) {
    return "Index: " index ", Size: " size;
}

/**
 * 从此列表中删除指定集合中包含的所有元素。
 */
public boolean removeAll(Collection<?> c) {
    Objects.requireNonNull(c);
    //如果此列表被修改则返回true
    return batchRemove(c, false);
}

/**
 * 仅保留此列表中包含在指定集合中的元素。
 *换句话说,从此列表中删除其中不包含在指定集合中的所有元素。
 */
public boolean retainAll(Collection<?> c) {
    Objects.requireNonNull(c);
    return batchRemove(c, true);
}


/**
 * 从列表中的指定位置开始,返回列表中的元素(按正确顺序)的列表迭代器。
 *指定的索引表示初始调用将返回的第一个元素为next 。 初始调用previous将返回指定索引减1的元素。
 *返回的列表迭代器是fail-fast 。
 */
public ListIterator<E> listIterator(int index) {
    if (index < 0 || index > size)
        throw new IndexOutOfBoundsException("Index: " index);
    return new ListItr(index);
}

/**
 *返回列表中的列表迭代器(按适当的顺序)。
 *返回的列表迭代器是fail-fast 。
 */
public ListIterator<E> listIterator() {
    return new ListItr(0);
}

/**
 *以正确的顺序返回该列表中的元素的迭代器。
 *返回的迭代器是fail-fast 。
 */
public Iterator<E> iterator() {
    return new Itr();
}

0 人点赞