这篇笔记主要记录一些不常用方法,了解一下可以干什么,有个印象。
改变数组容量
/** * 将该<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(); } }
来源:oschina
链接:https://my.oschina.net/u/3488841/blog/4294139