java常用类介绍及源码阅读(ArrayList)
?
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()? ??????????按適當順序(從第一個到最后一個元素)返回包含此列表中所有元素的數組。 | |
| 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)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构课上笔记5
- 下一篇: leetcode191. 位1的个数