java.util 
类 ArrayList<E>

继承关系:

java.lang.Objectjava.util.AbstractCollection<E>java.util.AbstractList<E>java.util.ArrayList<E>

List 接口的动态数组的实现。

实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。(此类大致上等同于 Vector 类,除了此类是不同步的。)

效率:

size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。add 操作以分摊的固定时间 运行,也就是说,添加 n 个元素需要 O(n) 时间。其他所有操作都以线性时间运行(大体上讲)。与用于 LinkedList 实现的常数因子相比,此实现的常数因子较低。

容量:

每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单。

在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。

多线程:

注意,此实现不是同步的。如果多个线程同时访问一个 ArrayList 实例,而其中至少一个线程从结构上修改了列表,那么它必须 保持外部同步。(结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法将该列表“包装”起来。这最好在创建时完成,以防止意外对列表进行不同步的访问:

        List list = Collections.synchronizedList(new ArrayList(...)); 

迭代器:

此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。

注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检测 bug。

此类是 Java Collections Framework 的成员。

构造方法摘要
ArrayList() 
          构造一个初始容量为 10 的空列表。
ArrayList(Collection<? extends E> c) 
          构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
ArrayList(int initialCapacity) 
          构造一个具有指定初始容量的空列表。
方法摘要
 boolean add(E e) 
          将指定的元素添加到此列表的尾部。
 void add(int index, E element) 
          将指定的元素插入此列表中的指定位置。
 boolean addAll(Collection<? extends E> c) 
          按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。
 boolean addAll(int index, Collection<? extends E> c) 
          从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
 void clear() 
          移除此列表中的所有元素。
 Object clone() 
          返回此 ArrayList 实例的浅表副本。
 boolean contains(Object o) 
          如果此列表中包含指定的元素,则返回 true。
 void ensureCapacity(int minCapacity) 
          如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。
 E get(int index) 
          返回此列表中指定位置上的元素。
 int indexOf(Object o) 
          返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
 boolean isEmpty() 
          如果此列表中没有元素,则返回 true
 int lastIndexOf(Object o) 
          返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。
 E remove(int index) 
          移除此列表中指定位置上的元素。
 boolean remove(Object o) 
          移除此列表中首次出现的指定元素(如果存在)。
protected  void removeRange(int fromIndex, int toIndex) 
          移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。
 E set(int index, E element) 
          用指定的元素替代此列表中指定位置上的元素。
 int size() 
          返回此列表中的元素数。
 Object[] toArray() 
          按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。
<T> T[]
toArray(T[] a) 
          按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。
 void trimToSize() 
          将此 ArrayList 实例的容量调整为列表的当前大小。

下面为源码解析:

package java.util;import sun.misc.SharedSecrets;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable {private static final long serialVersionUID = 8683452581122892189L;/*** 默认容量*/private static final int DEFAULT_CAPACITY = 10;/*** 对象数组*/private static final Object[] EMPTY_ELEMENTDATA = {};/*** 默认的空数组,无参构造函数创建的数组*/private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};/*** 存放数据的数组的缓存变量*/transient Object[] elementData;/*** 元素数量* */private int size;/*** 带有容量的构造方法* * @param 数组的初始容量* @throws IllegalArgumentException 参数为负*/public ArrayList(int initialCapacity) {// 参数>0if (initialCapacity > 0) {// new一个object数组赋给elementDatathis.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {// 参数=0// 将空数组赋给elementDatathis.elementData = EMPTY_ELEMENTDATA;} else {//参数<0,抛出IllegalArgumentException异常throw new IllegalArgumentException("Illegal Capacity: " +initialCapacity);}}/*** 不带参数构造方法*/public ArrayList() {// 将空数组赋给elementDatathis.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}/*** 带参数Collection的构造方法* * @param c*            其元素将被放入此列表中的集合* @throws NullPointerException*             集合为空*/public ArrayList(Collection<? extends E> c) {elementData = c.toArray();if ((size = elementData.length) != 0) {// c.toArray可能(错误地)不返回对象[](JAVA BUG编号6260652)if (elementData.getClass() != Object[].class)// Array.copyOf()主要用来将原数组拷贝到一个新的数组,适用于数组扩容。elementData = Arrays.copyOf(elementData, size, Object[].class);} else {// 空数组this.elementData = EMPTY_ELEMENTDATA;}}/*** 因为容量基本会大于实际元素的数量。内存紧张时,可以调用该方法调整容量为元素实际数量。* 如果确定不会有元素添加进来时也可以调用该方法来节约空间*/public void trimToSize() {modCount++;// 如果size小于lengthif (size < elementData.length) {// 将elementData设置大小为sizeelementData = (size == 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);}}/*** 使用指定参数设置数组容量* * @param minCapacity*            所需的最小容量*/public void ensureCapacity(int minCapacity) {// 如果数组为空,容量预取0,否则去默认值(10)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);}}private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;}/*** 得到最小扩容量* * @param minCapacity*/private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}/*** 判断是否需要扩容* * @param minCapacity*/private void ensureExplicitCapacity(int minCapacity) {modCount++;// 最小需要空间比elementData的内存空间大if (minCapacity - elementData.length > 0)grow(minCapacity);}/*** 数组的最大容量,可能会导致内存溢出*/private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;/*** 扩容* * @param minCapacity*            所需的最小容量*/private void grow(int minCapacity) {// ArrayList中elementData的内存空间长度int oldCapacity = elementData.length;// 扩容原来的1.5倍int newCapacity = oldCapacity + (oldCapacity >> 1);// 判断新数组的容量够不够// 不够就将数组长度设置为需要的长度if (newCapacity - minCapacity < 0)newCapacity = minCapacity;// 预设值>默认的最大值,检查溢出if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// 放到新数组中elementData = Arrays.copyOf(elementData, newCapacity);}/*** 检查是否溢出,若没有溢出,返回最大整数值或默认最大值* * @param minCapacity* @return*/private static int hugeCapacity(int minCapacity) {if (minCapacity < 0)   // 溢出throw new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}/*** 返回ArrayList的大小* * @return ArrayList中的元素数量*/public int size() {return size;}/*** 返回是否为空* * @return true 如果ArrayList中无元素*/public boolean isEmpty() {return size == 0;}/*** 是否包含一个数 返回bool* * @param o*            被检查元素* @return true 如果ArrayList中包含o元素*/public boolean contains(Object o) {return indexOf(o) >= 0;}/*** 返回一个值首次出现的位置,不存在就返回-1。时间复杂度O(N)* * 返回第一个null* @param o* @return*/public int indexOf(Object o) {if (o == null) {for (int i = 0; i < size; i++)if (elementData[i] == null)return i;} else {for (int i = 0; i < size; i++)if (o.equals(elementData[i]))return i;}return -1;}/*** 返回一个值最后一次出现的位置,不存在就返回-1。时间复杂度O(N)* 返回最后一个null* @param o* @return*/public int lastIndexOf(Object o) {if (o == null) {for (int i = size - 1; i >= 0; i--)if (elementData[i] == null)return i;} else {for (int i = size - 1; i >= 0; i--)if (o.equals(elementData[i]))return i;}return -1;}/*** 返回副本,元素本身没有被复制,复制过程中数组发生改变会抛出异常* * @return v ArrayList副本*/public Object clone() {try {// 调用Object类的clone方法得到ArrayList副本ArrayList<?> v = (ArrayList<?>) super.clone();// 调用copyOf,将ArrayList的elementData数组赋给副本的elementData数组v.elementData = Arrays.copyOf(elementData, size);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneablethrow new InternalError(e);}}/*** 转换为Object数组* * @return 一个数组包含所有列表中的元素*/public Object[] toArray() {return Arrays.copyOf(elementData, size);}/*** 将ArrayList里面的元素赋值到一个数组中去* a的长度小于ArrayList的长度,直接调用Arrays类的copyOf* a的长度大于ArrayList的长度,调用System.arraycopy,然后把size位置赋值为空。* * @param a*            如果它的长度大的话,列表元素存储在这个数组中; 否则分配一个新数组。* @return 一个包含ArrayList元素的数组* @throws ArrayStoreException*             将与数组类型不兼容的值赋值给数组元素时抛出的异常* @throws NullPointerException*             数组为空*/@SuppressWarnings("unchecked")public <T> T[] toArray(T[] a) {if (a.length < size)// 创建一个新的a的运行时类型数组,内容不变return (T[]) Arrays.copyOf(elementData, size, a.getClass());System.arraycopy(elementData, 0, a, 0, size);if (a.length > size)a[size] = null;return a;}/*** 返回指定位置的值* @param index* @return*/@SuppressWarnings("unchecked")E elementData(int index) {return (E) elementData[index];}/*** 返回指定位置的值,先检查是否超出数组长度* * @param index*            元素的索引* @return ArrayList中指定位置的元素* @throws IndexOutOfBoundsException*             {@inheritDoc}*/public E get(int index) {// 检查是否越界rangeCheck(index);// 返回ArrayList的elementData数组index位置的元素return elementData(index);}/*** 设置指定位置为一个新值,返回之前的值* * @param index*            要替换的元素的索引* @param element*            要存储在指定位置的元素* @return 之前在指定位置的元素* @throws IndexOutOfBoundsException*             {@inheritDoc}*/public E set(int index, E element) {// 检查越界rangeCheck(index);// 获取当前位置的值E oldValue = elementData(index);// 将element赋值到index位置elementData[index] = element;return oldValue;}/*** 添加一个值,首先会确保容量* * @param e*            要添加到此列表中的元素* @return <tt>true</tt> (as specified by {@link Collection#add})*/public boolean add(E e) {// 扩容ensureCapacityInternal(size + 1);// 将e赋值给elementData的size+1的位置elementData[size++] = e;return true;}/*** index位置添加元素element,会检查添加的位置和容量* * @param index*            指定元素将被插入的索引* @param element*            要插入的元素* @throws IndexOutOfBoundsException*             {@inheritDoc}*/public void add(int index, E element) {// 判断越界rangeCheckForAdd(index);// 扩容ensureCapacityInternal(size + 1);  // Increments modCount!!// 将elementData从index位置开始,复制到elementData的index+1开始的连续空间System.arraycopy(elementData, index, elementData, index + 1,size - index);// 在index位置赋值elementelementData[index] = element;// ArrayList的大小++size++;}/*** 移除index位置的元素,会检查去除的位置* * @param index*            要删除的元素的索引* @return 删除的元素* @throws IndexOutOfBoundsException*             {@inheritDoc}*/public E remove(int index) {// 判断越界rangeCheck(index);modCount++;// 读取旧值E oldValue = elementData(index);// 获取index位置开始到最后一个位置的个数int numMoved = size - index - 1;if (numMoved > 0)// index+1位置开始拷贝到从index开始的空间System.arraycopy(elementData, index + 1, elementData, index,numMoved);elementData[--size] = null; // 便于垃圾回收器回收return oldValue;}/*** 移除对象为O的元素,跟indexOf方法思想基本一致* @param o*            要从该列表中删除的元素(如果存在)* @return 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;}/*** 快速删除指定位置的值,不需要检查和返回值* * @param index*/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; // 便于垃圾回收器回收}/*** 清空数组,把每一个值设为null,方便垃圾回收(不同于reset,数组默认大小有改变的话不会重置)*/public void clear() {modCount++;// 便于垃圾回收器回收for (int i = 0; i < size; i++)elementData[i] = null;size = 0;}/*** 添加一个集合的元素到末端* * @param c*            包含要添加到此列表中的元素的集合* @return true 如果该列表因添加而改变* @throws NullPointerException*             如果指定的集合是空的*/public boolean addAll(Collection<? extends E> c) {// c转换为数组aObject[] a = c.toArray();// a占的内存空间长度赋值给numNewint numNew = a.length;// 扩容至size + numNewensureCapacityInternal(size + numNew);// 将a的第0位开始拷贝至elementData的size位开始,拷贝长度为numNewSystem.arraycopy(a, 0, elementData, size, numNew);// 将size增加numNewsize += numNew;return numNew != 0;}/*** 从第index位开始,将c全部拷贝到ArrayList* * @param index*            在哪个索引开始插入* @param c*            包含要添加到此列表中的元素的集合* @return true 如果该列表因添加而改变* @throws IndexOutOfBoundsException*             {@inheritDoc}* @throws NullPointerException*             如果指定的集合是空的*/public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);// 将c转换为数组aObject[] a = c.toArray();int numNew = a.length;// 扩容至size + numNewensureCapacityInternal(size + numNew);// 获取需要添加的个数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;}/*** 删除指定范围元素。* * @throws IndexOutOfBoundsException*             if {@code fromIndex} or {@code toIndex} is out of range ({@code fromIndex < 0 ||*             fromIndex >= size() || toIndex > size() || toIndex <*             fromIndex})*/protected void removeRange(int fromIndex, int toIndex) {modCount++;int numMoved = size - toIndex;// 后段保留的长度System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);// 便于垃圾回收int newSize = size - (toIndex - fromIndex);for (int i = newSize; i < size; i++) {elementData[i] = null;}size = newSize;}/*** 检查index是否超出数组长度*/private void rangeCheck(int index) {// 如果下标超过ArrayList的数组长度if (index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** 检查是否溢出*/private void rangeCheckForAdd(int index) {if (index > size || index < 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** 抛出的异常的详情*/private String outOfBoundsMsg(int index) {return "Index: " + index + ", Size: " + size;}/*** ArrayList移除集合c中的所有元素* * @param c*            包含要从此列表中移除的元素的集合* @return {@code true} 如果该列表因移除而改变* @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 removeAll(Collection<?> c) {// 如果c为空,则抛出空指针异常Objects.requireNonNull(c);// 调用batchRemove移除c中的元素return batchRemove(c, false);}/*** 仅保留指定集合c中的元素* * @param c*            collection containing elements to be retained in this list* @return {@code true} if this list changed as a result of the call* @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);// 调用batchRemove保留c中的元素return batchRemove(c, true);}/*** 根据complement值,将ArrayList中包含c中元素的元素删除或者保留* * @param c* @param complement*            true时从数组保留指定集合中元素的值,为false时从数组删除指定集合中元素的值。* @return 数组中重复的元素都会被删除(而不是仅删除一次或几次),有任何删除操作都会返回true*/private boolean batchRemove(Collection<?> c, boolean complement) {final Object[] elementData = this.elementData;// 定义一个w,一个r,两个同时右移int r = 0, w = 0;boolean modified = false;try {// r先右移for (; r < size; r++)// 如果c中不包含elementData[r]这个元素if (c.contains(elementData[r]) == complement)// 则直接将r位置的元素赋值给w位置的元素,w自增elementData[w++] = elementData[r];} finally {// 防止抛出异常导致上面r的右移过程没完成if (r != size) {// 将r未右移完成的位置的元素赋值给w右边位置的元素System.arraycopy(elementData, r,elementData, w,size - r);// 修改w值增加size-rw += size - r;}// 如果有被覆盖掉的元素,则将w后面的元素都赋值为nullif (w != size) {// clear to let GC do its workfor (int i = w; i < size; i++)elementData[i] = null;modCount += size - w;// 改变的次数// 新的大小为保留的元素的个数size = w;modified = true;}}return modified;}/*** 保存数组实例的状态到一个流(即序列化)。写入过程数组被更改会抛出异常* * @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 stuffint expectedModCount = modCount;// 执行默认的反序列化/序列化过程。将当前类的非静态和非瞬态字段写入此流s.defaultWriteObject();// 写入大小s.writeInt(size);// 写入所有元素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;// 执行默认的序列化/反序列化过程s.defaultReadObject();// 读入数组长度s.readInt(); // ignoredif (size > 0) {int capacity = calculateCapacity(elementData, size);SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);ensureCapacityInternal(size);Object[] a = elementData;// 读入所有元素for (int i = 0; i < size; i++) {a[i] = s.readObject();}}}/*** 返回一个从index开始的ListIterator对象* * @throws IndexOutOfBoundsException*             {@inheritDoc}*/public ListIterator<E> listIterator(int index) {if (index < 0 || index > size)throw new IndexOutOfBoundsException("Index: " + index);return new ListItr(index);}/*** 返回一个ListIterator对象,ListItr为ArrayList的一个内部类,实现了ListIterator<E> 接口* * @see #listIterator(int)*/public ListIterator<E> listIterator() {return new ListItr(0);}/*** 返回一个Iterator对象,Itr为ArrayList的一个内部类,实现了Iterator<E>接口* * @return an iterator over the elements in this list in proper sequence*/public Iterator<E> iterator() {return new Itr();}/*** 通用的迭代器实现*/private class Itr implements Iterator<E> {int cursor;       // 下一个元素的索引,默认为0int lastRet = -1; // 上次访问的元素的位置int expectedModCount = modCount;// 迭代过程修改数组抛出异常// 是否还有下一个public boolean hasNext() {return cursor != size;}// 下一个元素@SuppressWarnings("unchecked")public E next() {checkForComodification();// 检查数组是否被修改int i = cursor;if (i >= size)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;// 向后移动游标return (E) elementData[lastRet = i];// 设置访问的位置并返回这个值}// 删除元素public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();// 检查数组是否被修改try {ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}@Override@SuppressWarnings("unchecked")public void forEachRemaining(Consumer<? super E> consumer) {Objects.requireNonNull(consumer);final int size = ArrayList.this.size;int i = cursor;if (i >= size) {return;}final Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length) {throw new ConcurrentModificationException();}while (i != size && modCount == expectedModCount) {consumer.accept((E) elementData[i++]);}// update once at end of iteration to reduce heap write trafficcursor = i;lastRet = i - 1;checkForComodification();}// 检查数组是否被修改final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}/*** ListIterator迭代器实现*/private class ListItr extends Itr implements ListIterator<E> {ListItr(int index) {super();cursor = index;}public boolean hasPrevious() {return cursor != 0;}public int nextIndex() {return cursor;}public int previousIndex() {return cursor - 1;}@SuppressWarnings("unchecked")public E previous() {checkForComodification();int i = cursor - 1;if (i < 0)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i;return (E) elementData[lastRet = i];}public void set(E e) {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.set(lastRet, e);} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}public void add(E e) {checkForComodification();try {int i = cursor;ArrayList.this.add(i, e);cursor = i + 1;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}}/*** * 该方法返回的是父list的一个视图,fromIndex(包含)到toIndex(不包含)。fromIndex=toIndex 表示子list为空*/public List<E> subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, 0, fromIndex, toIndex);}/*** 安全检查* * @param fromIndex* @param toIndex* @param size*/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 + ")");}/*** 子数组*/private class SubList extends AbstractList<E> implements RandomAccess {private final AbstractList<E> parent;private final int parentOffset;private final int offset;int size;SubList(AbstractList<E> parent,int offset, int fromIndex, int toIndex) {this.parent = parent;this.parentOffset = fromIndex;this.offset = offset + fromIndex;this.size = toIndex - fromIndex;this.modCount = ArrayList.this.modCount;}public E set(int index, E e) {rangeCheck(index);checkForComodification();E oldValue = ArrayList.this.elementData(offset + index);ArrayList.this.elementData[offset + index] = e;return oldValue;}public E get(int index) {rangeCheck(index);checkForComodification();return ArrayList.this.elementData(offset + index);}public int size() {checkForComodification();return this.size;}public void add(int index, E e) {rangeCheckForAdd(index);checkForComodification();parent.add(parentOffset + index, e);this.modCount = parent.modCount;this.size++;}public E remove(int index) {rangeCheck(index);checkForComodification();E result = parent.remove(parentOffset + index);this.modCount = parent.modCount;this.size--;return result;}protected void removeRange(int fromIndex, int toIndex) {checkForComodification();parent.removeRange(parentOffset + fromIndex,parentOffset + toIndex);this.modCount = parent.modCount;this.size -= toIndex - fromIndex;}public boolean addAll(Collection<? extends E> c) {return addAll(this.size, c);}public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);int cSize = c.size();if (cSize == 0)return false;checkForComodification();parent.addAll(parentOffset + index, c);this.modCount = parent.modCount;this.size += cSize;return true;}public Iterator<E> iterator() {return listIterator();}public ListIterator<E> listIterator(final int index) {checkForComodification();rangeCheckForAdd(index);final int offset = this.offset;return new ListIterator<E>() {int cursor = index;int lastRet = -1;int expectedModCount = ArrayList.this.modCount;public boolean hasNext() {return cursor != SubList.this.size;}@SuppressWarnings("unchecked")public E next() {checkForComodification();int i = cursor;if (i >= SubList.this.size)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (offset + i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;return (E) elementData[offset + (lastRet = i)];}public boolean hasPrevious() {return cursor != 0;}@SuppressWarnings("unchecked")public E previous() {checkForComodification();int i = cursor - 1;if (i < 0)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (offset + i >= elementData.length)throw new ConcurrentModificationException();cursor = i;return (E) elementData[offset + (lastRet = i)];}@SuppressWarnings("unchecked")public void forEachRemaining(Consumer<? super E> consumer) {Objects.requireNonNull(consumer);final int size = SubList.this.size;int i = cursor;if (i >= size) {return;}final Object[] elementData = ArrayList.this.elementData;if (offset + i >= elementData.length) {throw new ConcurrentModificationException();}while (i != size && modCount == expectedModCount) {consumer.accept((E) elementData[offset + (i++)]);}// update once at end of iteration to reduce heap write// trafficlastRet = cursor = i;checkForComodification();}public int nextIndex() {return cursor;}public int previousIndex() {return cursor - 1;}public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {SubList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = ArrayList.this.modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}public void set(E e) {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.set(offset + lastRet, e);} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}public void add(E e) {checkForComodification();try {int i = cursor;SubList.this.add(i, e);cursor = i + 1;lastRet = -1;expectedModCount = ArrayList.this.modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}final void checkForComodification() {if (expectedModCount != ArrayList.this.modCount)throw new ConcurrentModificationException();}};}/*** 返回指定范围的子数组* * @param fromIndex* @param toIndex* @return*/public List<E> subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, offset, fromIndex, toIndex);}private void rangeCheck(int index) {if (index < 0 || index >= this.size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private void rangeCheckForAdd(int index) {if (index < 0 || index > this.size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private String outOfBoundsMsg(int index) {return "Index: " + index + ", Size: " + this.size;}private void checkForComodification() {if (ArrayList.this.modCount != this.modCount)throw new ConcurrentModificationException();}public Spliterator<E> spliterator() {checkForComodification();return new ArrayListSpliterator<E>(ArrayList.this, offset,offset + this.size, this.modCount);}}/*** Java 8 lambda 使用流遍历数组*/@Overridepublic 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();}}/*** 为了并行遍历元素而设计的一个迭代器* @return a {@code Spliterator} over the elements in this list* @since 1.8*/@Overridepublic Spliterator<E> spliterator() {return new ArrayListSpliterator<>(this, 0, -1, 0);}/*** Index-based split-by-two, lazily initialized Spliterator*/static final class ArrayListSpliterator<E> implements Spliterator<E> {/**
//forEach()private final ArrayList<E> list;private int index; // current index, modified on advance/splitprivate int fence; // -1 until used; then one past last indexprivate int expectedModCount; // initialized when fence set/*** Create new spliterator covering the given range*/ArrayListSpliterator(ArrayList<E> list, int origin, int fence,int expectedModCount) {this.list = list; // OK if null unless traversedthis.index = origin;this.fence = fence;this.expectedModCount = expectedModCount;}private int getFence() { // initialize fence to size on first useint hi; // (a specialized variant appears in method forEach)ArrayList<E> lst;if ((hi = fence) < 0) {if ((lst = list) == null)hi = fence = 0;else {expectedModCount = lst.modCount;hi = fence = lst.size;}}return hi;}public ArrayListSpliterator<E> trySplit() {int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;return (lo >= mid) ? null : // divide range in half unless too smallnew ArrayListSpliterator<E>(list, lo, index = mid,expectedModCount);}public boolean tryAdvance(Consumer<? super E> action) {if (action == null)throw new NullPointerException();int hi = getFence(), i = index;if (i < hi) {index = i + 1;@SuppressWarnings("unchecked") E e = (E) list.elementData[i];action.accept(e);if (list.modCount != expectedModCount)throw new ConcurrentModificationException();return true;}return false;}public void forEachRemaining(Consumer<? super E> action) {int i, hi, mc; // hoist accesses and checks from loopArrayList<E> lst;Object[] a;if (action == null)throw new NullPointerException();if ((lst = list) != null && (a = lst.elementData) != null) {if ((hi = fence) < 0) {mc = lst.modCount;hi = lst.size;} elsemc = expectedModCount;if ((i = index) >= 0 && (index = hi) <= a.length) {for (; i < hi; ++i) {@SuppressWarnings("unchecked") E e = (E) a[i];action.accept(e);}if (lst.modCount == mc)return;}}throw new ConcurrentModificationException();}public long estimateSize() {return (long) (getFence() - index);}public int characteristics() {return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;}}@Overridepublic 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 unmodifiedint 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// elementsfinal 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;}@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++;}@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++;}
}

java常用类介绍及源码阅读(ArrayList)相关推荐

  1. java常用类介绍及源码阅读(LinkedList)

    java.util  类 LinkedList<E> java.lang.Objectjava.util.AbstractCollection<E>java.util.Abst ...

  2. 17 任务调度相关类综述——Live555源码阅读(一)任务调度相关类

    这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...

  3. 16 BasicHashTable基本哈希表类(三)——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  4. java 自定义arraylist_Java 中模仿源码自定义ArrayList

    Java 中模仿源码自定义ArrayList 最近看了下ArrayList的源码,抽空根据ArrayList的底层结构写了一个功能简单无泛型的自定义ArrayLsit,帮助自己更好理解ArrayLis ...

  5. java jdk 类加载机制_JDK源码阅读之类加载

    java类加载 类的生命周期(类加载过程) LLIUU+VPR 加载(Loading) 链接(Linking) 验证(Verification) 准备(Preparation) 解析(Resoluti ...

  6. 【java】java 定时任务线程池 ScheduledThreadPoolExecutor 源码阅读

    文章目录 1.概述 1.1 问题 1.2 简介 1.2 数据结构 2.源码解析 2.1 内部类ScheduledFutureTask 2.1.1 compareTo 2.1.2 核心方法run() 2 ...

  7. java spring ioc 实例_Spring 源码阅读(IOC容器)-bean的实例化以及注入

    3.Bean的实例化以及注入过程分析 Bean的实例以及注入是在getBean时触发的,由于外部容器是与外部调用交互的桥梁,我们首先从外部容器入手,AbstractApplicationContext ...

  8. Java常用类全面解析(含部分源码)

    常用类 文章目录 常用类 字符串相关的类 String 类 说明 案例 String 的实例方式 String 中的常用方法 案例一 案例二 案例三 String 类与其它结构之间的转换 小复习-与基 ...

  9. java io中断_JDK源码阅读:InterruptibleChannel 与可中断 IO

    来源:木杉的博客 , imushan.com/2018/08/01/java/language/JDK源码阅读-InterruptibleChannel与可中断IO/ Java传统IO是不支持中断的, ...

最新文章

  1. 微信小程序使用阿里巴巴iconfont字体图标
  2. shell的数字、字符串处理
  3. 'yii\base\InvalidRouteException' with message 'Unable to resolve the request site/error.'
  4. (血和泪的成果)使用PageHelper分页插件进行后台分页
  5. 2019年10个最受欢迎的JavaScript动画库!
  6. 阻塞、非阻塞、超时(同步与异步)
  7. 船舶定位实时查询系统_港口人员精准定位系统,实时安全管控与智能预警
  8. CALL 和 ret 指令
  9. 数字万用表校准软件|数字万用表自动计量系统NSAT-3030
  10. aws基础架构学习笔记
  11. 暴力破解Windows密码(二、三):使用getpass内存提取windows用户密码、使用quarkpwdump导出windows用户密码hash值
  12. 视频教程-SpringBoot核心技术-Java
  13. 常用或特别的人类fasta参考基因组下载链接
  14. echarts tooltip提示框 自定义小圆点(颜色、形状和大小等等)
  15. 360视频加速器官方版
  16. freeswitch对接ims
  17. 这几个宝藏网站助力学好Python
  18. 2022 开源免费的 WordPress 主题推荐-大盘站
  19. 程序员该不该主动提加薪?
  20. Redis之主从复制原理 详解

热门文章

  1. MATLAB 求曲线长度
  2. 修改了WINCE自带的驱动程序后如何编译
  3. mysql 碎片率_计算MySQL表碎片的SQL整理
  4. themyleaf 图片上传_javaEE --springboot #实现图片上传和回显 #单文件上传 #多文件上传 #ajax异步文件上传 (非常详细,从创建项目开始)...
  5. idea lombok不生效_Spring Boot 集成 Lombok 让代码更简洁!
  6. 解决mapgis比例尺不正确问题
  7. Sharepoint学习笔记—ECM系列--4 根据位置设置的默认元数据值(Location-Based Metadata Defaults)
  8. 第十一节:特性(常见的特性标签、自定义特性、特性的使用案例)
  9. python中赋值运算符有哪些_Python代码中有哪些赋值运算符呢?
  10. plus 什么是mybais_谈谈自己用mybatis-plus中的一些经验。