Java集合Collection源码系列-ArrayList源码分析
Java集合系列-ArrayList源碼分析
文章目錄
- Java集合系列-ArrayList源碼分析
- 前言
- 一、為什么想去分析ArrayList源碼?
- 二、源碼分析
- 1.宏觀上分析List
- 2.方法匯總
- 三、ArrayList基本說明
- 總結(jié)
前言
一、為什么想去分析ArrayList源碼?
大家都懂,這個很重要
備注: 源碼分析系列全部基于jdk8
二、源碼分析
1.宏觀上分析List
代碼如下(示例):
public interface List<E> extends Collection<E>可以看到list其實是一個接口,繼承與Collection.
2.方法匯總
1. 獲取list的大小,最大為Integer.MAX_VALUE個元素:
int size();2. 判斷集合是否有元素
boolean isEmpty(); //判斷集合是否有元素3. 判斷一個集合是否包含某一個元素,可能出現(xiàn)。ClassCastException和NullPointerException異常
boolean contains(Object o);4. 返回一個迭代器
Iterator<E> iterator();5. 轉(zhuǎn)換為一個對象數(shù)組
Object[] toArray();6. 集合轉(zhuǎn)換為一個數(shù)組,元素類型根據(jù)泛型獲得
<T> T[] toArray(T[] a);基本使用方法
import java.util.ArrayList; import java.util.Arrays; import java.util.List;public class Demo {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);Integer[] array = list.toArray(new Integer[0]);Arrays.stream(array).forEach(System.out::println);} }這里的list.toArray(new Integer[0])和list.toArray()是一樣的
7. 向集合中添加一個元素
boolean add(E e)8. 移除集合中的一個元素,移除的是第一個出現(xiàn)的元素
boolean remove(Object o);9. 是否包含一個集合
boolean containsAll(Collection<?> c);10. 向list集合中添加一個集合
boolean addAll(Collection<? extends E> c);11. 在指定位置插入集合
boolean addAll(int index, Collection<? extends E> c);12. 移除指定的所有集合
boolean removeAll(Collection<?> c);13. 移除指定的所有集合
boolean retainAll(Collection<?> c);listA.retainAll(listB);保留 A中包含在集合B中的元素或者說移除A中沒有在B中的元素
15. 用函數(shù)接口的返回結(jié)果替代原list中的值.
參考: replaceAll較為詳細(xì)的解釋
16. 排序方法
default void sort(Comparator<? super E> c) {Object[] a = this.toArray();Arrays.sort(a, (Comparator) c);ListIterator<E> i = this.listIterator();for (Object e : a) {i.next();i.set((E) e);}}參考sort的使用方法
17. 移除list的所有元素
void clear();18. 判斷兩個list是否相等
In other words, two lists are defined to be equal if they contain the same elements in the same order.
boolean equals(Object o);19. 獲取list的hash值
int hashCode();20. 獲取指定位置的元素
E get(int index);21. 設(shè)置指定位置的元素的值
E set(int index, E element);22. 在指定位置添加值
E set(int index, E element);23. 移除指定位置的元素
E remove(int index);24. 獲取指定元素的索引
int indexOf(Object o);25. 獲取元素最后一次出現(xiàn)的索引值
int lastIndexOf(Object o);26. 移除指定位置的元素
E remove(int index);27. 返回一個迭代器,可以雙向遍歷
ListIterator<E> listIterator();參考listIterator的使用方法
29. 返回一個迭代器,可以雙向遍歷
30. 獲取list的一個指定范圍的子集
List<E> subList(int fromIndex, int toIndex);31. 移除指定位置的元素
default Spliterator<E> spliterator() {return Spliterators.spliterator(this, Spliterator.ORDERED);}參考spliterator的使用方法
三、ArrayList基本說明
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.)
- ArrayList是list接口的一種實現(xiàn),是一個可變大小的數(shù)組
- 實現(xiàn)了list所有可選擇的操作,并且允許null元素的存在
- 除了實現(xiàn)list的接口,這個類提供了操作數(shù)組大小的方法,在內(nèi)部,可以利用這個數(shù)組來存儲list
- ArrayList和Vector是類似的,但是ArrayList是非同步(unsynchronized)的, 其實也就是說ArrayList是非線程安全的,Vector是線程安全的。
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.
- 方法size、isEmpty、get、set、iterator、listIterator都是常數(shù)時間
- 方法add 運行是amortized constant time 分?jǐn)偝?shù)時間,也就是說,向數(shù)組中添加一個元素,時間復(fù)雜度為O(n)
- 所有其他的操作算法時間復(fù)雜度都是O(1)
- 與LinkedList相比較而言,list有更小的常數(shù)因子
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)
- 容量具體指的是用來存放列表中元素的數(shù)組的大小
- 隨著元素添加到ArrayList中,其容量是在不斷自動增加的
- 增加策略的詳細(xì)信息并沒有特別指定,除了增加一個元素到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.
- 在添加大量的元素到arrayList之前,是可以使用ensureCapacity來增加ArrayList的容量大小的
- 使用ensureCapacity可以減少需要重新分配內(nèi)存的數(shù)量
-
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.
- 需要注意的是ArrayList并不是線程安全的
- 在并發(fā)的場景下,如果至少有一個線程來修改list的結(jié)構(gòu),那么我們需要外部保證必須同步(結(jié)構(gòu)性修改可以是add、delete或者調(diào)整backing array數(shù)組大小中的任意一個操作;僅僅只是設(shè)置list中一個元素的值不是結(jié)構(gòu)性的修改)
- 典型的實現(xiàn)是,用synchronize修飾某些包裹encapsulate了整個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(...));- (承接上文)如果沒有一個encapsulate了這個list的對象存在,那么應(yīng)該使用Collections.synchronizedList,來防止對list意外的非同步訪問
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.
- iterator()和istIterator(int)方法是快速失敗的,并拋出ConcurrentModificationException: 如果這個list在創(chuàng)建了iterator以后,在任意時刻被結(jié)構(gòu)性修改,除了iterator自身調(diào)用remove和add方法
- 因此在并發(fā)修改的場景下,這個迭代器快速失敗而不是在未來一個不確定性的時間冒險專斷或者不確定性行為
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.
- 需要注意的是,一般說來,迭代器快速失敗的行為不能做出保證,因為它不可能在出現(xiàn)非同步并發(fā)修改時做出任何保證;基于最大努力,快速失敗的迭代器拋出ConcurrentModificationException異常
- 因此,寫一個基于這個異常來做修正的代碼是不正確的;迭代器快速失敗的行為應(yīng)該僅僅被用來檢測bug
# 四、ArrayList基本說明 public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
- ArrayList繼承了抽象的list-AbstractList
- 實現(xiàn)了List、RandomAccess、Cloneable和java.io.Serializable 4個接口
- 默認(rèn)的初始化容器大小
- 共享的空數(shù)組實例,用來當(dāng)作空的實例,容器大小為0
- 共享的空數(shù)組實例,用作默認(rèn)大小的空實例,容器大小為10
- 與上面的EMPTY_ELEMENTDATA的區(qū)別在于當(dāng)?shù)谝粋€元素添加進去的時候,我們知道需要擴多大的容量
- 作為數(shù)組緩存,來存放ArrayList中的元素
- ArrayList數(shù)組容量的大小時這個緩存數(shù)組的長度
- 任何元素為DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList,在第一次添加元素時,會擴張為DEFAULT_CAPACITY
- ArrayList中包含有元素的個數(shù),注意與capacity的區(qū)別
- 構(gòu)造器,構(gòu)造一個指定大小的ArrayList
- 構(gòu)造器,構(gòu)造一個初始化容量大小為10的空ArrayList
- 通過一個集合來構(gòu)造ArrayList
- 構(gòu)造器總結(jié): 三個構(gòu)造器,1)指定大小 2) 默認(rèn)大小 3)利用集合
- 這個函數(shù)是用來調(diào)整容器為當(dāng)前列表所包含的元素的個數(shù)(size)
- modCount,這個參數(shù)在講AbstractList內(nèi)部類迭代器的時候,具體講解,主要是用來記錄list被結(jié)構(gòu)性修改次數(shù)的
- 另外就是elementData,在上面也講過,它是用來作為一個緩存,來存放ArrayList中的元素的
- 用來增加當(dāng)前ArrayList實例的容量大小
- 確保能夠包含所指定的最小容量大小個數(shù)的元素
如果用來存放list的緩存數(shù)組的長度elementData.length小于所設(shè)定的最小容量minCapacity,那么就需要進行擴容
private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));} private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity; }- grow—擴容相關(guān)的代碼
- MAX_ARRAY_SIZE 表述數(shù)組所允許分配的最大大小
- grow函數(shù)用來擴容elementData數(shù)組,來確保可以存放所設(shè)置的minCapacity個元素
- 這里擴容的原理:默認(rèn)是比原來的大小新增0.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
(1) 如果擴容以后的newCapacity比需要的minCapacity小,則直接將newCapacity修改為minCapacity;
(2)如果擴容以后的newCapacity比需要的minCapacity大,并且比最大值MAX_ARRAY_SIZE都還要大,則需要調(diào)用hugeCapacity,比較minCapacity和MAX_ARRAY_SIZE的大小,如果minCapacity大于MAX_ARRAY_SIZE,則將newCapacity設(shè)置為Integer.MAX_VALUE,否則設(shè)置為MAX_ARRAY_SIZE(Integer.MAX_VALUE - 8),那么這里為什么是MAX.VALUE-8,則是因為數(shù)組作為一個對象,需要一定的內(nèi)存存儲對象頭信息,對象頭信息最大占用內(nèi)存不可超過8字節(jié)。參考
(3) 然后將舊數(shù)組拷貝到新數(shù)組 參考
elementData = Arrays.copyOf(elementData, newCapacity); - 關(guān)于這里為什么要調(diào)用ensureCapacity:當(dāng)我們已經(jīng)確定了要插入的對象的數(shù)目(并不是在創(chuàng)建ArrayList之前就知道有多少對象要插入的情況),就應(yīng)該首先調(diào)用ensureCapacity來一次性擴容到可以容得下要插入的對象個數(shù),這樣就避免的多次進行數(shù)組拷貝的情況,提高了效率,算是優(yōu)化吧;當(dāng)然,我們在創(chuàng)建ArrayList之前就知道有多少對象要插入就使用有參構(gòu)造。參考
- 返回list中的元素個數(shù)
- 判斷l(xiāng)ist中是否有元素
- 判斷l(xiāng)ist中是否包含某個對象,這里我們在判斷一個list元素為自定義對象的時候,需要重寫equal和hashCode方法,這里才能判斷是否包含某個對象,下面的demo會返回false
- 返回list中指定元素第一次出現(xiàn)時的位置,這個位置是在elementData這個數(shù)組中的位置,這里需要注意如果需要元素為null時的判斷
- 返回list中指定元素最后一次出現(xiàn)時的位置,這里需要注意如果需要元素為null時的判斷
- 返回對當(dāng)前ArrayList實例的一個淺拷貝
- 將list轉(zhuǎn)化為數(shù)組,這里的數(shù)組是重新分配的一個空間,不會和原來的list元素存在任何引用關(guān)系,因此調(diào)用者可以自由的修改數(shù)組中的元素
- 和上面的方法類似
下面開始講元素操作部分
@SuppressWarnings("unchecked")E elementData(int index) {return (E) elementData[index];}- 獲取指定位置index的元素
- 判斷元素是否在指定范圍內(nèi)
- 設(shè)置指定位置元素的值
- 向list中添加一個元素
(1) 添加元素是添加在內(nèi)部數(shù)組的最后一個位置
(2) ensureCapacityInternal方法,add()方法的時候,會導(dǎo)致list發(fā)生結(jié)構(gòu)性的修改,然后需要將modCount進行+1操作
- 在指定位置添加元素的值
(1) 檢查所要添加的位置是否在合理范圍
/*** A version of rangeCheck used by add and addAll.*/private void rangeCheckForAdd(int index) {if (index > size || index < 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}(2) 調(diào)用ensureCapacityInternal(size + 1),增加修改計數(shù)器modCount和判斷是否需要擴容
(3) 移動數(shù)組元素,將源數(shù)組src的從起始位置srcPos開始的元素 復(fù)制到目標(biāo)數(shù)組dest的從destPos開始長度為length的數(shù)組位置
(4) 然后將element賦值到指定位置elementData[index] = element;,最后修改整個list的大小size++
- 移除指定位置的元素
(1) rangeCheck(index); 先檢查需要移除的位置index是否合理
(2) 修改標(biāo)志修改次數(shù)的參數(shù)值 modCount++
(3) 調(diào)整數(shù)組
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
(4) 將數(shù)組的最后一個位置置為null,方便gc;然后計算list的大小
(5) 返回所移除的元素
- 移除指定元素
(1) 快速移除 fastRemove,省去了邊界檢查
- 清空列表
- 添加集合到list的末尾,這個操作行為的結(jié)果是不確定的,如果要添加的集合在添加的過程中被修改
- 插入集合到指定位置
- 移除指定范圍(左閉右開)的元素
- 將集合C中存在與list中的元素移除走
(1) 如果c.contains(elementData[r]) == false,也就是說當(dāng)前l(fā)ist中位于位置r的元素不在c中,那么就將r位置的元素放到當(dāng)前l(fā)ist的對應(yīng)位置為w的地方
(2) 上面的代碼 什么情況下會發(fā)生r != size的情況
(3) 另外這里的removeAll指的是把含在c中的元素從list中移除,而不是如果c中有一個元素不在list中,則不進行移除
- 將集合C中存在與list中的元素保留下來
- 序列化writeObject和反序列化readObject
迭代器------Itr
- 根據(jù)當(dāng)前的list返回一個迭代器Iterator
- list的內(nèi)部類 迭代器Itr,是AbstractList的迭代器Itr的一個優(yōu)化版本
- 核心變量
cursor—下一個元素的索引值
lastRet—上一次返回元素的索引值
expectedModCount —期望被修改的次數(shù)
- 判斷迭代器是否還有更多的元素,下一個元素的索引cursor是否為list的大小size
- 獲取迭代器的下一個元素的值
(1) 檢查修改次數(shù) 期望修改的次數(shù)expectedModCount和實際修改次數(shù)是否相同
final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}(2) 判斷下一個元素的索引是否超過了list的大小size
(3) 將當(dāng)前l(fā)ist轉(zhuǎn)化為數(shù)組 Object[] elementData = ArrayList.this.elementData;
(4) 判斷下一個元素的索引值是否超過了當(dāng)前數(shù)組elementData的長度,這里為什么需要做這個判斷
(5) 修改cursor的指,指向當(dāng)前要返回元素的下一個元素的索引位置 cursor = i + 1;
(6) 返回當(dāng)前索引值 return (E) elementData[lastRet = i];
- 移除上一個返回的元素
移除上一個返回的元素以后:
(1) 下一個元素的索引值cursor為上一個返回元素的索引
(2) 上一個返回元素的索引為-1
(3) 修改期望修改值expectedModCount
- 為list中剩余的每一個元素執(zhí)行指定的操作
(1) 先判斷當(dāng)前迭代器所指向下一個元素的索引是否超過了當(dāng)前l(fā)ist的大小size
(2) 先判斷當(dāng)前迭代器所指向下一個元素的索引是否超過了當(dāng)前緩存數(shù)組的長度length
(3) 然后為剩下的每一個元素都執(zhí)行consumer.accept((E) elementData[i++]);
(4) 更新參數(shù) cursor = I; lastRet = i - 1;
內(nèi)部類 ListItr
/*** An optimized version of AbstractList.ListItr*/private class ListItr extends Itr implements ListIterator<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)throw new IndexOutOfBoundsException("Index: "+index);return new ListItr(index);}- 返回一個從指定位置開始的list iterator
- 指定位置表明 第一個元素將是初次調(diào)用next方法返回的
- 初次調(diào)用previous方法會返回指定位置-1處的元素
- ListItr 繼承Itr, 實現(xiàn)接口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()}.
- ListIterator是一個針對lists的迭代器,這個迭代器允許程序以不同的方向去遍歷list、在迭代的過程中修改list和獲取迭代器在list的當(dāng)前位置
- ListIterator 沒有當(dāng)前的元素
- ListIterator的cursor position總是處于調(diào)用者調(diào)用previous()所返回的值和調(diào)用者調(diào)用next()所返回的值之間
An iterator for a list of length {@code n} has {@code n+1} possible cursor positions, as illustrated by the carets ({@code ^}) below:
Element(0) Element(1) Element(2) … Element(n-1)cursor positions: ^ ^ ^ ^ ^
- 一個作為長度為n的list的迭代器有n+1個可能的cusor位置
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 而是使用 調(diào)用next或者previous方法返回的上一個元素lastRet
- ListItr構(gòu)造器
- 利用ListItr反向遍歷list的時候,判斷是否有上一個元素
- 針對一系列調(diào)用next方法時,返回的元素的索引值
- 針對一系列調(diào)用previous方法時,返回的元素的索引值
- 獲取cursor所在位置的前面一個位置的值
- 設(shè)置上一個返回值的位置的值為元素e
- 在下一個元素的索引位置處設(shè)置值e
- subList方法將返回當(dāng)前l(fā)ist在指定范圍(左閉右開區(qū)間范圍)的list元素
- 如果區(qū)間范圍邊界值fromIndex和toIndex值相同,那么返回的list為空
- 這個返回的list是和原來的list是有關(guān)系的,返回list的結(jié)構(gòu)性改變會引起原list的結(jié)構(gòu)性改變,反過來也一樣。
- 返回來的這個list是SubList支持list的所有操作,因為繼承了AbstractList, 重寫了對應(yīng)的方法
內(nèi)部類 SubList
private class SubList extends AbstractList<E> implements RandomAccess-
SubList繼承了AbstractList,實現(xiàn)了 RandomAccess
-
RandomAccess 表示list接口的實現(xiàn)類支持快速隨機訪問
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.
- 內(nèi)部變量
- 構(gòu)造器
- 設(shè)置指定位置的元素為e
(1)與ArrayList的方法進行比較,多了modCount的比較和設(shè)置對應(yīng)的值時增加了偏移量
public E set(int index, E element) {rangeCheck(index);E oldValue = elementData(index);elementData[index] = element;return oldValue;}- 獲取指定位置的元素值
- 獲取大小
- 在指定位置添加元素
- 移除指定位置的元素
- 移除指定范圍的元素
- 添加集合
- 在指定位置添加集合
- 返回迭代器
- 返回可以前后遍歷list的迭代器,里面包含了ListItr相應(yīng)的方法,比如 next,previous
- SubList類也包含了sublist方法
- spliterator()方法,這里涉及到內(nèi)部類ArrayListSpliterator,后面會詳細(xì)講這個類的作用
至此,SubList的所有方法就講完了,現(xiàn)在來繼續(xù)講解ArrayList的剩余方法
- 為list中每一個元素執(zhí)行相同的操作
- List item
內(nèi)部類 ArrayListSpliterator
/** Index-based split-by-two, lazily initialized Spliterator */static final class ArrayListSpliterator<E> implements Spliterator<E>- 基于索引
- 一分為二
- 延遲初始化的可拆分的迭代器 參考
- 該對象可以使用trySplit進行迭代器拆分,每次拆分后的迭代器接近上一次的二分之一。
這是官方對于大數(shù)據(jù)量數(shù)組多線程遍歷加工的一種趨勢性指引。參考
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.
- 局部變量
(1) index 當(dāng)前索引,在遍歷或者拆分的時候被修改
(2) fence 沒使用的時候默認(rèn)為-1,最后指向最后一個索引
- 構(gòu)造器
- 初始化變量fence,在第一次使用的初始化fence到list的大小
- 拆分ArrayList
- 當(dāng)前元素執(zhí)行action
- 剩下的元素執(zhí)行相同的操作
- 估計大小
- 返回這個拆分迭代器和里面元素的特征
- 按照一定規(guī)則過濾集合中的元素
- 用于將給定的操作內(nèi)容替換掉數(shù)組中每一個元素。
- List 排序
ArrayList的整體框架 參考
總結(jié)
總結(jié)
以上是生活随笔為你收集整理的Java集合Collection源码系列-ArrayList源码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: unity2d游戏开发系列教程:一、环境
- 下一篇: thinksns+ 安装,处理安装过程中