defaultvoidreplaceAll(UnaryOperator<E> operator){Objects.requireNonNull(operator);final ListIterator<E> li =this.listIterator();while(li.hasNext()){li.set(operator.apply(li.next()));}}
參考: replaceAll較為詳細的解釋
16. 排序方法
defaultvoidsort(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);}}
參考sort的使用方法
17. 移除list的所有元素
voidclear();
18. 判斷兩個list是否相等
In other words, two lists are defined to be equal if they contain the same elements in the same order.
Resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null. In addition to implementing the List interface,this class provides methods to manipulate the size of the array that is used internally to store the list. (This class is roughly equivalent to Vector, except that it is c.)
The size, isEmpty, get, set iterator, and listIterator operations run in constant time. The add operation runs in amortized constant time,that is, adding n elements requires O(n) time. All of the other operations run in linear time (roughly speaking). The constant factor is low compared to that for the LinkedList implementation.
方法add 運行是amortized constant time 分攤常數時間,也就是說,向數組中添加一個元素,時間復雜度為O(n)
所有其他的操作算法時間復雜度都是O(1)
與LinkedList相比較而言,list有更小的常數因子
Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added to an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.
每一個ArrayList實例都有一個容量(capacity)
容量具體指的是用來存放列表中元素的數組的大小
隨著元素添加到ArrayList中,其容量是在不斷自動增加的
增加策略的詳細信息并沒有特別指定,除了增加一個元素到ArrayList需要amortized constant time
An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation. This may reduce the amount of incremental reallocation.
Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently,and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the list.
If no such object exists, the list should be “wrapped” using the {@link Collections#synchronizedList Collections.synchronizedList} method. This is best done at creation time, to prevent accidental unsynchronized access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
The iterators returned by this class's {@link #iterator() iterator} and {@link #listIterator(int) listIterator} methods are fail-fast:if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own {@link ListIterator#remove() remove} or {@link ListIterator#add(Object) add} methods, the iterator will throw a {@link ConcurrentModificationException}. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw {@code ConcurrentModificationException} on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.
/*** Shared empty array instance used for empty instances.*/privatestaticfinal Object[] EMPTY_ELEMENTDATA ={};
共享的空數組實例,用來當作空的實例,容器大小為0
/*** 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 ={};
/*** 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
/*** The size of the ArrayList (the number of elements it contains).** @serial*/privateint size;
ArrayList中包含有元素的個數,注意與capacity的區別
/*** Constructs an empty list with the specified initial capacity.** @param initialCapacity the initial capacity of the list* @throws IllegalArgumentException if the specified initial capacity* is negative*/publicArrayList(int initialCapacity){if(initialCapacity >0){this.elementData =newObject[initialCapacity];}elseif(initialCapacity ==0){this.elementData = EMPTY_ELEMENTDATA;}else{thrownewIllegalArgumentException("Illegal Capacity: "+initialCapacity);}}
構造器,構造一個指定大小的ArrayList
/*** Constructs an empty list with an initial capacity of ten.*/publicArrayList(){this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
構造器,構造一個初始化容量大小為10的空ArrayList
/*** Constructs a list containing the elements of the specified* collection, in the order they are returned by the collection's* iterator.** @param c the collection whose elements are to be placed into this list* @throws NullPointerException if the specified collection is null*/publicArrayList(Collection<?extendsE> c){elementData = c.toArray();if((size = elementData.length)!=0){// c.toArray might (incorrectly) not return Object[] (see 6260652)if(elementData.getClass()!= Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);}else{// replace with empty array.this.elementData = EMPTY_ELEMENTDATA;}}
通過一個集合來構造ArrayList
構造器總結: 三個構造器,1)指定大小 2) 默認大小 3)利用集合
/*** 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);}}
/*** Increases the capacity of this <tt>ArrayList</tt> instance, if* necessary, to ensure that it can hold at least the number of elements* specified by the minimum capacity argument.** @param minCapacity the desired minimum capacity*/publicvoidensureCapacity(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);}}
/*** The maximum size of array to allocate.* Some VMs reserve some header words in an array.* Attempts to allocate larger arrays may result in* OutOfMemoryError: Requested array size exceeds VM limit*/privatestaticfinalint MAX_ARRAY_SIZE = Integer.MAX_VALUE -8;/*** Increases the capacity to ensure that it can hold at least the* number of elements specified by the minimum capacity argument.** @param minCapacity the desired minimum capacity*/privatevoidgrow(int minCapacity){// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity +(oldCapacity >>1);if(newCapacity - minCapacity <0)newCapacity = minCapacity;if(newCapacity - MAX_ARRAY_SIZE >0)newCapacity =hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);}privatestaticinthugeCapacity(int minCapacity){if(minCapacity <0)// overflowthrownewOutOfMemoryError();return(minCapacity > MAX_ARRAY_SIZE)?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}
/*** Returns the number of elements in this list.** @return the number of elements in this list*/publicintsize(){return size;}
返回list中的元素個數
/*** Returns <tt>true</tt> if this list contains no elements.** @return <tt>true</tt> if this list contains no elements*/publicbooleanisEmpty(){return size ==0;}
判斷list中是否有元素
/*** 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* <tt>(o==null ? e==null : o.equals(e))</tt>.** @param o element whose presence in this list is to be tested* @return <tt>true</tt> if this list contains the specified element*/publicbooleancontains(Object o){returnindexOf(o)>=0;}
publicclassDemo{publicstaticvoidmain(String[] args){List<Student> list =newArrayList<>();Student A =newStudent();A.setName("A");A.setAge(1);Student B =newStudent();B.setName("B");B.setAge(2);list.add(A);list.add(B);Student C =newStudent();C.setName("A");C.setAge(1);System.out.println(list.contains(C));}}/*** Returns the index of the first occurrence of the specified element* in this list, or -1 if this list does not contain the element.* More formally, returns the lowest index <tt>i</tt> such that* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,* or -1 if there is no such index.*/publicintindexOf(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;}
/*** Returns the index of the last occurrence of the specified element* in this list, or -1 if this list does not contain the element.* More formally, returns the highest index <tt>i</tt> such that* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,* or -1 if there is no such index.*/publicintlastIndexOf(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;}
返回list中指定元素最后一次出現時的位置,這里需要注意如果需要元素為null時的判斷
/*** Returns a shallow copy of this <tt>ArrayList</tt> instance. (The* elements themselves are not copied.)** @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 CloneablethrownewInternalError(e);}}
返回對當前ArrayList實例的一個淺拷貝
/*** 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.** @return an array containing all of the elements in this list in* proper sequence*/public Object[]toArray(){return Arrays.copyOf(elementData, size);}
/*** 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.)** @param a the array into which the elements of the list are to* be stored, if it is big enough; otherwise, a new array of the* same runtime type is allocated for this purpose.* @return an array containing the elements of the list* @throws ArrayStoreException if the runtime type of the specified array* is not a supertype of the runtime type of every element in* this list* @throws NullPointerException if the specified array is null*/@SuppressWarnings("unchecked")public<T> T[]toArray(T[] a){if(a.length < size)// 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;}
/*** Returns the element at the specified position in this list.** @param index index of the element to return* @return the element at the specified position in this list* @throws IndexOutOfBoundsException {@inheritDoc}*/public E get(int index){rangeCheck(index);returnelementData(index);}
判斷元素是否在指定范圍內
/*** 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));}
設置指定位置元素的值
/*** Replaces the element at the specified position in this list with* the specified element.** @param index index of the element to replace* @param element element to be stored at the specified position* @return the element previously at the specified position* @throws IndexOutOfBoundsException {@inheritDoc}*/public E set(int index, E element){rangeCheck(index);E oldValue =elementData(index);elementData[index]= element;return oldValue;}
向list中添加一個元素
/*** Appends the specified element to the end of this list.** @param e element to be appended to this list* @return <tt>true</tt> (as specified by {@link Collection#add})*/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).** @param index index at which the specified element is to be inserted* @param element element to be inserted* @throws IndexOutOfBoundsException {@inheritDoc}*/publicvoidadd(int index, E element){rangeCheckForAdd(index);ensureCapacityInternal(size +1);// Increments modCount!!System.arraycopy(elementData, index, elementData, index +1,size - index);elementData[index]= element;size++;}
(1) 檢查所要添加的位置是否在合理范圍
/*** A version of rangeCheck used by add and addAll.*/privatevoidrangeCheckForAdd(int index){if(index > size || index <0)thrownewIndexOutOfBoundsException(outOfBoundsMsg(index));}
/*** Removes the element at the specified position in this list.* Shifts any subsequent elements to the left (subtracts one from their* indices).** @param index the index of the element to be removed* @return the element that was removed from the list* @throws IndexOutOfBoundsException {@inheritDoc}*/public E remove(int index){rangeCheck(index);modCount++;E oldValue =elementData(index);int numMoved = size - index -1;if(numMoved >0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size]= null;// clear to let GC do its workreturn 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).** @param o element to be removed from this list, if present* @return <tt>true</tt> if this list contained the specified element*/publicbooleanremove(Object o){if(o == null){for(int index =0; index < size; index++)if(elementData[index]== null){fastRemove(index);returntrue;}}else{for(int index =0; index < size; index++)if(o.equals(elementData[index])){fastRemove(index);returntrue;}}returnfalse;}/** Private remove method that skips bounds checking and does not* return the value removed.*/privatevoidfastRemove(int index){modCount++;int numMoved = size - index -1;if(numMoved >0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size]= null;// clear to let GC do its work}
(1) 快速移除 fastRemove,省去了邊界檢查
清空列表
/*** 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 workfor(int i =0; i < size; i++)elementData[i]= null;size =0;}
添加集合到list的末尾,這個操作行為的結果是不確定的,如果要添加的集合在添加的過程中被修改
/*** 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.)** @param c collection containing elements to be added to this list* @return <tt>true</tt> if this list changed as a result of the call* @throws NullPointerException if the specified collection is null*/publicbooleanaddAll(Collection<?extendsE> c){Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew);// Increments modCountSystem.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.** @param index index at which to insert the first element from the* specified collection* @param c collection containing elements to be added to this list* @return <tt>true</tt> if this list changed as a result of the call* @throws IndexOutOfBoundsException {@inheritDoc}* @throws NullPointerException if the specified collection is null*/publicbooleanaddAll(int index, Collection<?extendsE> c){rangeCheckForAdd(index);Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew);// Increments modCountint 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;}
移除指定范圍(左閉右開)的元素
/*** 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.)** @throws IndexOutOfBoundsException if {@code fromIndex} or* {@code toIndex} is out of range* ({@code fromIndex < 0 ||* fromIndex >= size() ||* toIndex > size() ||* toIndex < fromIndex})*/protectedvoidremoveRange(int fromIndex,int toIndex){modCount++;int numMoved = size - toIndex;System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);// clear to let GC do its workint newSize = size -(toIndex-fromIndex);for(int i = newSize; i < size; i++){elementData[i]= null;}size = newSize;}
將集合C中存在與list中的元素移除走
/*** Removes from this list all of its elements that are contained in the* specified collection.** @param c collection containing elements to be removed from 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)*/publicbooleanremoveAll(Collection<?> c){Objects.requireNonNull(c);returnbatchRemove(c,false);}privatebooleanbatchRemove(Collection<?> c,boolean complement){final Object[] elementData =this.elementData;int r =0, w =0;boolean modified =false;try{for(; r < size; r++)if(c.contains(elementData[r])== complement)elementData[w++]= elementData[r];}finally{// Preserve behavioral compatibility with AbstractCollection,// even if c.contains() throws.if(r != size){System.arraycopy(elementData, r,elementData, w,size - r);w += size - r;}if(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;}
/*** 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.** @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)*/publicbooleanretainAll(Collection<?> c){Objects.requireNonNull(c);returnbatchRemove(c,true);}
序列化writeObject和反序列化readObject
/*** Save the state of the <tt>ArrayList</tt> instance to a stream (that* is, serialize it).** @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.*/privatevoidwriteObject(java.io.ObjectOutputStream s)throws java.io.IOException{// Write out element count, and any hidden stuffint 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){thrownewConcurrentModificationException();}}/*** Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,* deserialize it).*/privatevoidreadObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {elementData = EMPTY_ELEMENTDATA;// Read in size, and any hidden stuffs.defaultReadObject();// Read in capacitys.readInt();// ignoredif(size >0){// be like clone(), allocate array based upon size not capacityint 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();}}}
迭代器------Itr
根據當前的list返回一個迭代器Iterator
public Iterator<E>iterator(){returnnewItr();}
list的內部類 迭代器Itr,是AbstractList的迭代器Itr的一個優化版本
*** An optimized version of AbstractList.Itr*/privateclassItrimplementsIterator<E>{
/*** An optimized version of AbstractList.ListItr*/privateclassListItrextendsItrimplementsListIterator<E>{/*** 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.** <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.** @throws IndexOutOfBoundsException {@inheritDoc}*/public ListIterator<E>listIterator(int index){if(index <0|| index > size)thrownewIndexOutOfBoundsException("Index: "+index);returnnewListItr(index);}
返回一個從指定位置開始的list iterator
指定位置表明 第一個元素將是初次調用next方法返回的
初次調用previous方法會返回指定位置-1處的元素
/*** 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>.** @see #listIterator(int)*/public ListIterator<E>listIterator(){returnnewListItr(0);}
ListItr 繼承Itr, 實現接口ListIterator
接口ListIterator
An iterator for lists that allows the programmer to traverse the list in either direction, modify the list during iteration, and obtain the iterator’s current position in the list. A {@code ListIterator} has no current element; its cursor position always lies between the element that would be returned by a call to {@code previous()} and the element that would be returned by a call to {@code next()}.
Note that the {@link #remove} and {@link #set(Object)} methods are not defined in terms of the cursor position; they are defined to operate on the last element returned by a call to {@link #next} or {@link #previous()}.
注意remove和set方法并不是使用cursor position 而是使用 調用next或者previous方法返回的上一個元素lastRet
ListItr構造器
ListItr(int index){super();cursor = index;}
利用ListItr反向遍歷list的時候,判斷是否有上一個元素
publicbooleanhasPrevious(){return cursor !=0;}
針對一系列調用next方法時,返回的元素的索引值
publicintnextIndex(){return cursor;}
針對一系列調用previous方法時,返回的元素的索引值
publicintpreviousIndex(){return cursor -1;}}
獲取cursor所在位置的前面一個位置的值
public E previous(){checkForComodification();int i = cursor -1;if(i <0)thrownewNoSuchElementException();Object[] elementData = ArrayList.this.elementData;if(i >= elementData.length)thrownewConcurrentModificationException();cursor = i;return(E) elementData[lastRet = i];}
publicvoidadd(E e){checkForComodification();try{int i = cursor;ArrayList.this.add(i, e);cursor = i +1;lastRet =-1;expectedModCount = modCount;}catch(IndexOutOfBoundsException ex){thrownewConcurrentModificationException();}}/*** Returns a view of the portion of this list between the specified* {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If* {@code fromIndex} and {@code toIndex} are equal, the returned list is* empty.) The returned list is backed by this list, so non-structural* changes in the returned list are reflected in this list, and vice-versa.* The returned list supports all of the optional list operations.** <p>This method eliminates the need for explicit range operations (of* the sort that commonly exist for arrays). Any operation that expects* a list can be used as a range operation by passing a subList view* instead of a whole list. For example, the following idiom* removes a range of elements from a list:* <pre>* list.subList(from, to).clear();* </pre>* Similar idioms may be constructed for {@link #indexOf(Object)} and* {@link #lastIndexOf(Object)}, and all of the algorithms in the* {@link Collections} class can be applied to a subList.** <p>The semantics of the list returned by this method become undefined if* the backing list (i.e., this list) is <i>structurally modified</i> in* any way other than via the returned list. (Structural modifications are* those that change the size of this list, or otherwise perturb it in such* a fashion that iterations in progress may yield incorrect results.)** @throws IndexOutOfBoundsException {@inheritDoc}* @throws IllegalArgumentException {@inheritDoc}*/public List<E>subList(int fromIndex,int toIndex){subListRangeCheck(fromIndex, toIndex, size);returnnewSubList(this,0, fromIndex, toIndex);}staticvoidsubListRangeCheck(int fromIndex,int toIndex,int size){if(fromIndex <0)thrownewIndexOutOfBoundsException("fromIndex = "+ fromIndex);if(toIndex > size)thrownewIndexOutOfBoundsException("toIndex = "+ toIndex);if(fromIndex > toIndex)thrownewIllegalArgumentException("fromIndex("+ fromIndex +") > toIndex("+ toIndex +")");}
Marker interface used by List implementations to indicate that they support fast (generally constant time) random access. The primary purpose of this interface is to allow generic algorithms to alter their behavior to provide good performance when applied to either random or sequential access lists.
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;}
(1)與ArrayList的方法進行比較,多了modCount的比較和設置對應的值時增加了偏移量
public E set(int index, E element){rangeCheck(index);E oldValue =elementData(index);elementData[index]= element;return oldValue;}
獲取指定位置的元素值
public E get(int index){rangeCheck(index);checkForComodification();return ArrayList.this.elementData(offset + index);}
publicvoidadd(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;}
/*** Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>* and <em>fail-fast</em> {@link Spliterator} over the elements in this* list.** <p>The {@code Spliterator} reports {@link Spliterator#SIZED},* {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.* Overriding implementations should document the reporting of additional* characteristic values.** @return a {@code Spliterator} over the elements in this list* @since 1.8*/@Overridepublic Spliterator<E>spliterator(){returnnewArrayListSpliterator<>(this,0,-1,0);}
If ArrayLists were immutable, or structurally immutable (no adds, removes, etc), we could implement their spliterators with Arrays.spliterator. Instead we detect as much interference during traversal as practical without sacrificing much performance. We rely primarily on modCounts. These are not guaranteed to detect concurrency violations, and are sometimes overly conservative about within-thread interference, but detect enough problems to be worthwhile in practice. To carry this out, we (1) lazily initialize fence and expectedModCount until the latest point that we need to commit to the state we are checking against; thus improving precision. (This doesn’t apply to SubLists, that create spliterators with current non-lazy values). (2) We perform only a single ConcurrentModificationException check at the end of forEach (the most performance-sensitive method). When using forEach (as opposed to iterators), we can normally only detect interference after actions, not before. Further CME-triggering checks apply to all other possible violations of assumptions for example null or too-small elementData array given its size(), that could only have occurred due to interference. This allows the inner loop of forEach to run without any further checks, and simplifies lambda-resolution. While this does entail a number of checks, note that in the common case of list.stream().forEach(a), no checks or other computation occur anywhere other than inside forEach itself. The other less-often-used methods cannot take advantage of most of these streamlinings.
局部變量
privatefinal ArrayList<E> list;privateint index;// current index, modified on advance/splitprivateint fence;// -1 until used; then one past last indexprivateint expectedModCount;// initialized when fence set
(1) index 當前索引,在遍歷或者拆分的時候被修改 (2) fence 沒使用的時候默認為-1,最后指向最后一個索引
構造器
/** 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;}
初始化變量fence,在第一次使用的初始化fence到list的大小
privateintgetFence(){// 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;}
拆分ArrayList
public ArrayListSpliterator<E>trySplit(){int hi =getFence(), lo = index, mid =(lo + hi)>>>1;return(lo >= mid)? null :// divide range in half unless too smallnewArrayListSpliterator<E>(list, lo, index = mid,expectedModCount);}
當前元素執行action
publicbooleantryAdvance(Consumer<?super E> action){if(action == null)thrownewNullPointerException();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)thrownewConcurrentModificationException();returntrue;}returnfalse;}
剩下的元素執行相同的操作
publicvoidforEachRemaining(Consumer<?super E> action){int i, hi, mc;// hoist accesses and checks from loopArrayList<E> lst; Object[] a;if(action == null)thrownewNullPointerException();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;}}thrownewConcurrentModificationException();}
@OverridepublicbooleanremoveIf(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 =newBitSet(size);finalint expectedModCount = modCount;finalint 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){thrownewConcurrentModificationException();}// shift surviving elements left over the spaces left by removed elementsfinalboolean anyToRemove = removeCount >0;if(anyToRemove){finalint 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){thrownewConcurrentModificationException();}modCount++;}return anyToRemove;}