/** * 用于空实例的空数组 * Shared empty array instance used for empty instances. */ privatestaticfinal Object[] EMPTY_ELEMENTDATA = {};
/** * 用于默认大小空实例的共享空数组示例。和EMPTY_ELEMENTDATA区分开是为了知道添加第一个 * 元素时容量需要添加多少。 * * Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added. */ privatestaticfinal Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/** * 保存ArrayList数据的数组 * * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_CAPACITY when the first element is added. */ transient Object[] elementData; // non-private to simplify nested class access
/** * ArrayList中所包含的元素个数 * The size of the ArrayList (the number of elements it contains). * * @serial 是一个标签,用于记录序列化版本号的相关信息。 */ privateint size;
/** * 默认无参构造函数 * Constructs an empty list with an initial capacity of ten. */ publicArrayList() { // DEFAULTCAPACITY_EMPTY_ELEMENTDATA为空数组,初始化为10 => 初始是空数组,当添加第一个元素时 // 数组容量变为10 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
/** * 构造一个包含指定集合的元素的列表(按照由集合迭代器返回的顺序) * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's * iterator. */ publicArrayList(Collection<? extends E> c) { // 将指定的集合转化为数组 Object[] a = c.toArray(); // 如何数组的长度不为0 if ((size = a.length) != 0) { // 如果a数组的类型是ArryList类型,直接赋值给elementData if (c.getClass() == ArrayList.class) { elementData = a; } else { // 不是ArrayList类型,将原来不是ArrayList类型的数组内容赋值给新的Object类型的elementData数组 elementData = Arrays.copyOf(a, size, Object[].class); } } else { // 其他情况,使用空数组代替 // replace with empty array. elementData = EMPTY_ELEMENTDATA; } }
容器大小类
/** * 修改当前ArrayList实例的容量为列表的大小 * 应用程序可以使用此操作最小化ArrayList实例的存储 * * Trims the capacity of this <tt>ArrayList</tt> instance to be the * list's current size. An application can use this operation to minimize * the storage of an <tt>ArrayList</tt> instance. */ publicvoidtrimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); } } /** * 返回列表中的元素数 * Returns the number of elements in this list. */ publicintsize() { return size; }
/** * 如果此列表中不包含元素返回true * Returns <tt>true</tt> if this list contains no elements. */ publicbooleanisEmpty() { return size == 0; }
判断元素类
/** * 如果列表中包含了指定的元素o,返回true * Returns <tt>true</tt> if this list contains the specified element. * More formally, returns <tt>true</tt> if and only if this list contains * at least one element <tt>e</tt> such that */ publicbooleancontains(Object o) { return indexOf(o) >= 0; }
/** * 返回列表中指定元素首次出现的索引,如果不包含指定元素,返回-1 * Returns the index of the first occurrence of the specified element * in this list, or -1 if this list does not contain the element. */ publicintindexOf(Object o) { if (o == null) { for (inti=0; i < size; i++) if (elementData[i]==null) return i; } else { for (inti=0; i < size; i++) // 使用equals()方法比较 if (o.equals(elementData[i])) return i; } return -1; }
/** * 返回列表中指定元素最后一次出现的索引,如果不包含指定元素,返回-1 * Returns the index of the last occurrence of the specified element * in this list, or -1 if this list does not contain the element. */ publicintlastIndexOf(Object o) { if (o == null) { for (inti= size-1; i >= 0; i--) if (elementData[i]==null) return i; } else { for (inti= size-1; i >= 0; i--) if (o.equals(elementData[i])) return i; } return -1; }
拷贝相关
/** * 返回此ArrayList实例的浅拷贝(元素本身不被复制) * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The * elements themselves are not copied.) */ public Object clone() { try { ArrayList<?> v = (ArrayList<?>) super.clone(); // Arrays.copyOf()方法是实现数组的复制,返回复制后的数组,参数是被复制的数组和复制的长度 v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable thrownewInternalError(e); } }
转换数组
/** * 以一定的顺序(从第一个元素到最后一个元素)返回一个包含此列表中所有元素的数组 * 返回的数组是“安全的”,因为该列表不保留对它的引用(即这个方法分配了一个新的数组)。 * 因此调用者可以自由地修改返回的数组,此方法饰演阵列和基于集合的API之间的桥梁角色。 * Returns an array containing all of the elements in this list * in proper sequence (from first to last element). * * <p>The returned array will be "safe" in that no references to it are * maintained by this list. (In other words, this method must allocate * a new array). The caller is thus free to modify the returned array. * * <p>This method acts as bridge between array-based and collection-based * APIs. */ public Object[] toArray() { return Arrays.copyOf(elementData, size); }
/** * 以一定的顺序(从第一个元素到最后一个元素)返回一个包含此列表中所有元素的数组 * 返回的数组的运行时类型是指定数组的运行时类型。如果列表适合指定的数组,则返回该列表, * 否则,将为指定的数组的运行时类型和此列表的大小分配一个新数组。 * 如果列表适合指定的数组,其余空间(即数组的元素数量多余此列表元素数量),则紧跟在集合结束后的 * 数组中元素设置为null。 * Returns an array containing all of the elements in this list in proper * sequence (from first to last element); the runtime type of the returned * array is that of the specified array. If the list fits in the * specified array, it is returned therein. Otherwise, a new array is * allocated with the runtime type of the specified array and the size of * this list. * * <p>If the list fits in the specified array with room to spare * (i.e., the array has more elements than the list), the element in * the array immediately following the end of the collection is set to * <tt>null</tt>. (This is useful in determining the length of the * list <i>only</i> if the caller knows that the list does not contain * any null elements.) */ @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) // 新建一个运行时类型的数组,但是ArrayList数组的内容 // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; }
范围检查类
/** * 检查给定的索引是否在合法范围内 * Checks if the given index is in range. If not, throws an appropriate * runtime exception. This method does *not* check if the index is * negative: It is always used immediately prior to an array access, * which throws an ArrayIndexOutOfBoundsException if index is negative. */ privatevoidrangeCheck(int index) { if (index >= size) thrownewIndexOutOfBoundsException(outOfBoundsMsg(index)); }
/** * 检查添加元素的索引范围是否合法 * A version of rangeCheck used by add and addAll. */ privatevoidrangeCheckForAdd(int index) { if (index > size || index < 0) thrownewIndexOutOfBoundsException(outOfBoundsMsg(index)); } /** * Constructs an IndexOutOfBoundsException detail message. * Of the many possible refactorings of the error handling code, * this "outlining" performs best with both server and client VMs. */ private String outOfBoundsMsg(int index) { return"Index: "+index+", Size: "+size; }
元素操作类
/** * 返回此列表中指定位置的元素 * Returns the element at the specified position in this list. */ public E get(int index) { rangeCheck(index);
return elementData(index); }
/** * 用指定的元素替换此列表中指定位置的元素 * Replaces the element at the specified position in this list with * the specified element. */ public E set(int index, E element) { rangeCheck(index);
/** * 将指定的元素追加到列表的末尾 * Appends the specified element to the end of this list. */ publicbooleanadd(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; returntrue; }
/** * 在此列表中的指定元素插入指定的元素 * * Inserts the specified element at the specified position in this * list. Shifts the element currently at that position (if any) and * any subsequent elements to the right (adds one to their indices). */ publicvoidadd(int index, E element) { rangeCheckForAdd(index); // 范围检查
/** * 删除该列表中指定位置的元素 * Removes the element at the specified position in this list. * Shifts any subsequent elements to the left (subtracts one from their * indices). */ public E remove(int index) { rangeCheck(index);
modCount++; EoldValue= elementData(index);
intnumMoved= size - index - 1; if (numMoved > 0) // 将index + 1开始之后的元素左移一个位置 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work
return oldValue; // 返回从列表中删除的元素 }
/** * 从列表中删除指定元素(第一个出现在列表中的),如果不包含该元素,不会更改。 * Removes the first occurrence of the specified element from this list, * if it is present. If the list does not contain the element, it is * unchanged. More formally, removes the element with the lowest index * <tt>i</tt> such that * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> * (if such an element exists). Returns <tt>true</tt> if this list * contained the specified element (or equivalently, if this list * changed as a result of the call). */ publicbooleanremove(Object o) { if (o == null) { for (intindex=0; index < size; index++) if (elementData[index] == null) { fastRemove(index); returntrue; } } else { for (intindex=0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); returntrue; } } returnfalse; }
/** * 清空列表元素 * Removes all of the elements from this list. The list will * be empty after this call returns. */ publicvoidclear() { modCount++;
// clear to let GC do its work for (inti=0; i < size; i++) elementData[i] = null;
size = 0; }
/** * 按指定集合的Iterator返回的顺序将指定集合中的所有元素追加到此列表的末尾。 * Appends all of the elements in the specified collection to the end of * this list, in the order that they are returned by the * specified collection's Iterator. The behavior of this operation is * undefined if the specified collection is modified while the operation * is in progress. (This implies that the behavior of this call is * undefined if the specified collection is this list, and this * list is nonempty.) */ publicbooleanaddAll(Collection<? extends E> c) { Object[] a = c.toArray(); intnumNew= a.length; ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }
/** * 将指定集合中的所有元素插入到此列表中,从指定的位置开始。 * Inserts all of the elements in the specified collection into this * list, starting at the specified position. Shifts the element * currently at that position (if any) and any subsequent elements to * the right (increases their indices). The new elements will appear * in the list in the order that they are returned by the * specified collection's iterator. */ publicbooleanaddAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index);
/** * 从此列表中删除所有索引为 [fromIndex, toIndex) 之间的元素。 * 将任何后续元素左移(减少其索引) * Removes from this list all of the elements whose index is between * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. * Shifts any succeeding elements to the left (reduces their index). * This call shortens the list by {@code (toIndex - fromIndex)} elements. * (If {@code toIndex==fromIndex}, this operation has no effect.) */ protectedvoidremoveRange(int fromIndex, int toIndex) { modCount++; intnumMoved= size - toIndex; System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved);
// clear to let GC do its work intnewSize= size - (toIndex-fromIndex); for (inti= newSize; i < size; i++) { elementData[i] = null; } size = newSize; } /** * 此列表中删除指定集合中包含的所有元素。 * Removes from this list all of its elements that are contained in the * specified collection. */ publicbooleanremoveAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, false); }
/** * 仅保留此列表中包含在指定集合中的元素。 * Retains only the elements in this list that are contained in the * specified collection. In other words, removes from this list all * of its elements that are not contained in the specified collection. */ publicbooleanretainAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, true); }
迭代器相关
/** * 从列表中返回从指定位置开始的按照正确顺序的列表迭代器 * Returns a list iterator over the elements in this list (in proper * sequence), starting at the specified position in the list. * The specified index indicates the first element that would be * returned by an initial call to {@link ListIterator#next next}. * An initial call to {@link ListIterator#previous previous} would * return the element with the specified index minus one. */ public ListIterator<E> listIterator(int index) { if (index < 0 || index > size) thrownewIndexOutOfBoundsException("Index: "+index); returnnewListItr(index); }
/** * 返回列表中的列表迭代器(按适当的顺序)。 * 返回的列表迭代器是fail-fast 。 * Returns a list iterator over the elements in this list (in proper * sequence). * * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>. */ public ListIterator<E> listIterator() { returnnewListItr(0); }
/** * 以正确的顺序返回该列表中的元素的迭代器。 * 返回的迭代器是fail-fast 。 * Returns an iterator over the elements in this list in proper sequence. * * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>. */ public Iterator<E> iterator() { returnnewItr(); }
transient Object[] elementData; // non-private to simplify nested class access
在 Java 中,被 transient
修饰的对象默认不会被序列化。
那么在序列化后,ArrayList
里面的元素数组保存的数据不就完全丢失了吗?
其实并不会,ArrayList 提供了两个用于序列化和反序列化的方法,
readObject 和 writeObject。ArrayList
在序列化的时候会调用 writeObject,将 size 和 element
写入ObjectOutputStream; 反序列化时调用
readObject,从 ObjectInputStream 获取 size 和
element ,再恢复到 elementData。
@java.io.Serial privatevoidwriteObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out element count, and any hidden stuff intexpectedModCount= modCount; s.defaultWriteObject();
// Write out size as capacity for behavioral 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) { thrownewConcurrentModificationException(); } }
// Read in size, and any hidden stuff s.defaultReadObject();
// Read in capacity s.readInt(); // ignored
if (size > 0) { // like clone(), allocate array based upon size not capacity SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size); Object[] elements = newObject[size];
// Read in all elements in the proper order. for (inti=0; i < size; i++) { elements[i] = s.readObject(); }