ArrayList源码-不常用方法

自古美人都是妖i 提交于 2020-08-20 00:16:37

        这篇笔记主要记录一些不常用方法,了解一下可以干什么,有个印象。

    改变数组容量

/**
 * 将该<tt> ArrayList </ tt>实例的容量调整为列表的当前大小。
 * 应用程序可以使用此操作来最大程度地减少<tt> ArrayList </ tt>实例的存储。
 */
public void trimToSize() {
    modCount++;
    if (size < elementData.length) {
        elementData = (size == 0)
          ? EMPTY_ELEMENTDATA
          : Arrays.copyOf(elementData, size);
    }
}
/**
 * 如有必要,增加此<tt> ArrayList </ tt>实例的容量,以确保它至少可以容纳最小容量参数指定的元素数。
 *
 * @param   minCapacity   the desired minimum capacity
 */
public void ensureCapacity(int minCapacity) {
    int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        // any size if not default element table
        ? 0
        // larger than default for default empty table. It's already
        // supposed to be at default size.
        : DEFAULT_CAPACITY;

    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}

    克隆方法

/**
 * 返回此<tt> ArrayList </ tt>实例的浅复制。 (元素本身不会被复制。)
 * 复制的对象,其包含的每个元素并不是复制的,和源列表对象中的是一样的
 * @return a clone of this <tt>ArrayList</tt> instance
 */
public Object clone() {
    try {
        ArrayList<?> v = (ArrayList<?>) super.clone();
        v.elementData = Arrays.copyOf(elementData, size);
        v.modCount = 0;
        return v;
    } catch (CloneNotSupportedException e) {
        // this shouldn't happen, since we are Cloneable
        throw new InternalError(e);
    }
}

    删除操作

/**    
 * 仅保留此列表中包含在指定集合中的元素。
 * 换句话说,从该列表中删除所有未包含在指定集合中的元素。
 * @throws ClassCastException if the class of an element of this list
 *         is incompatible with the specified collection
 * (<a href="Collection.html#optional-restrictions">optional</a>)
 * @throws NullPointerException if this list contains a null element and the
 *         specified collection does not permit null elements
 * (<a href="Collection.html#optional-restrictions">optional</a>),
 *         or if the specified collection is null
 * @see Collection#contains(Object)
 */
public boolean retainAll(Collection<?> c) {
    Objects.requireNonNull(c);
    return batchRemove(c, true);
}//这个可以和 removeAll(Collection<?> c)  对比看一下

        下面这个方法是 jdk 1.8 引入的,重写了 Collection 中的removeIf 方法。

@Override
public boolean removeIf(Predicate<? super E> filter) {
    Objects.requireNonNull(filter);
    // figure out which elements are to be removed
    // any exception thrown from the filter predicate at this stage
    // will leave the collection unmodified
    int removeCount = 0;
    final BitSet removeSet = new BitSet(size);
    final int expectedModCount = modCount;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        @SuppressWarnings("unchecked")
        final E element = (E) elementData[i];
        if (filter.test(element)) {
            removeSet.set(i);
            removeCount++;
        }
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }

    // shift surviving elements left over the spaces left by removed elements
    final boolean anyToRemove = removeCount > 0;
    if (anyToRemove) {
        final int newSize = size - removeCount;
        for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
            i = removeSet.nextClearBit(i);
            elementData[j] = elementData[i];
        }
        for (int k=newSize; k < size; k++) {
            elementData[k] = null;  // Let gc do its work
        }
        this.size = newSize;
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }

    return anyToRemove;
}

        replaceAll 是 jdk 1.8 引入的,重写了 List 中的replaceAll 方法。

@Override
@SuppressWarnings("unchecked")
public void replaceAll(UnaryOperator<E> operator) {
    Objects.requireNonNull(operator);
    final int expectedModCount = modCount;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        elementData[i] = operator.apply((E) elementData[i]);
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
    modCount++;
}

    序列化(私有)

/**
 * 将 ArrayList 实例的状态保存到流中(即,对其进行序列化)。
 *
 * @serialData The length of the array backing the <tt>ArrayList</tt>
 *             instance is emitted (int), followed by all of its elements
 *             (each an <tt>Object</tt>) in the proper order.
 */
private void writeObject(java.io.ObjectOutputStream s)
    throws java.io.IOException{
    // Write out element count, and any hidden stuff
    int expectedModCount = modCount;
    s.defaultWriteObject();

    // Write out size as capacity for behavioural compatibility with clone()
    s.writeInt(size);

    // Write out all elements in the proper order.
    for (int i=0; i<size; i++) {
        s.writeObject(elementData[i]);
    }

    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
}
/**
 * 从流中重构 ArrayList 实例(即,将其反序列化)。
 */
private void readObject(java.io.ObjectInputStream s)
    throws java.io.IOException, ClassNotFoundException {
    elementData = EMPTY_ELEMENTDATA;

    // Read in size, and any hidden stuff
    s.defaultReadObject();

    // Read in capacity
    s.readInt(); // ignored

    if (size > 0) {
        // be like clone(), allocate array based upon size not capacity
        int capacity = calculateCapacity(elementData, size);
        SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);
        ensureCapacityInternal(size);

        Object[] a = elementData;
        // Read in all elements in the proper order.
        for (int i=0; i<size; i++) {
            a[i] = s.readObject();
        }
    }
}

    排序

         sort 方法是 jdk 1.8 引入的,重写了 List 中的sort 方法。

@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
    final int expectedModCount = modCount;
    Arrays.sort((E[]) elementData, 0, size, c);
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
    modCount++;
}

    List 接口中的默认实现

default void sort(Comparator<? super E> c) {
    Object[] a = this.toArray();
    Arrays.sort(a, (Comparator) c);
    ListIterator<E> i = this.listIterator();
    for (Object e : a) {
        i.next();
        i.set((E) e);
    }
}

    视图操作

        这个方法是在看List 接口源码才注意到的,返回的列表上做的非结构性修改会体现在源列表上,反之亦然。主要涉及到一个内部类 SubList ,提供的方法与 ArrayList 基本一致,代码太多就不贴了。

        

/**
 *  返回此列表在指定的<tt> fromIndex </ tt>(包括)和<tt> toIndex </ tt>(不包括)之间的视图。 
 *(如果<tt> fromIndex </ tt>和<tt> toIndex </ tt>相等,则返回列表为空。)
 * 返回列表由该列表支持,因此返回列表中的非结构性更改将反映在此列表,反之亦然。 
 * 返回的列表支持此列表支持的所有可选列表操作。 
 * 此方法消除了对显式范围操作(数组通常存在的那种范围)的需要。 通过传递subList视图而不是整个列表,
 * 可以将期望列表的任何操作用作范围操作。 例如,以下语法从列表中删除了一系列元素:
 * list.subList(from, to).clear();
 * 可以为{@link #indexOf(Object)}和{@link #lastIndexOf(Object)}构建类似的习惯用法,
 * 并且{@link Collections}类中的所有算法都可以应用于子列表。
 * 
 * 如果后备列表(即此列表)以除通过返回列表以外的任何其他方式进行<i>结构修改</ i>,则此方法返回的列表的语义将变得不确定。 
 * (结构修改是指更改此列表的大小的结构修改,或者以其他方式干扰此列表的方式,即正在进行的迭代可能会产生错误的结果。)
 * @throws IndexOutOfBoundsException {@inheritDoc}
 * @throws IllegalArgumentException {@inheritDoc}
 */
public List<E> subList(int fromIndex, int toIndex) {
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, 0, fromIndex, toIndex);
}

static void subListRangeCheck(int fromIndex, int toIndex, int size) {
    if (fromIndex < 0)
        throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
    if (toIndex > size)
        throw new IndexOutOfBoundsException("toIndex = " + toIndex);
    if (fromIndex > toIndex)
        throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                           ") > toIndex(" + toIndex + ")");
}

 

    遍历

        forEach 方法是 jdk 1.8 引入的,重写了 Itrable 中的sort 方法。

@Override
public void forEach(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    final int expectedModCount = modCount;
    @SuppressWarnings("unchecked")
    final E[] elementData = (E[]) this.elementData;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        action.accept(elementData[i]);
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
}

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!