arraylist元素是有序的,可重複。線程不安全的。底層維護一個 object 數組。
jdk1.7:arraylist像餓漢式,預設初始長度直接建立一個容量為 10 的數組。
jdk1.8:arraylist像懶漢式,預設一開始建立一個長度為 0 的數組,當添加第一個元素時再建立一個始容量為10的數組。
預設情況擴容都為原來數組的 1.5 倍。
繼承關系:
擴容原理:
①随機通路
由于實作了 randomaccess 接口,它支援通過索引值去随機通路元素。
②增強foreach,底層還是使用的疊代器
這種文法可以看成是 jdk 的一種文法糖,通過反編譯 class 檔案,可以看到生成的 java 檔案,還是通過調用 iterator 疊代器來周遊的。
③疊代器 iterator
④疊代器 listiterator
源碼示例:
繼承了abstractlist:abstractlist提供list接口的骨幹實作,以最大限度地減少"随機通路"資料存儲(如arraylist)實作llist所需的工作。
實作了 list 接口:定義了實作該接口的類都必須要實作的一組方法,實作了所有可選清單操作。
實作了 randmoaccess 接口:表明arraylist支援快速(通常是固定時間)随機通路。此接口的主要目的是允許一般的算法更改其行為,進而在将其應用到随機或連續通路清單時能提供良好的性能。比如在工具類 collections 中,應用二分查找方法時判斷是否實作了 randomaccess 接口:
實作了 cloneable 接口:一個标記接口,接口内無任何方法體和常量的聲明。需要複寫object.clone()函數,表示它可以被克隆。
實作了 serializable 接口:一個标記接口,辨別該類可序列化。
源碼示例:讀一下源碼中的英文注釋。
源碼示例:三個重載(重要)
arraylist list = new arraylist(); // 集合長度初始化是0,而不是 10,jdk7才是10。
arraylist list = new arraylist(7); // 指定大小時,初始多大就是多大。
傳入一個集合。
源碼示例:擴容原理
源碼示例:真正擴容的方法
說明:
modcount給arraylist的疊代器使用的,在并發修改時,提供快速失敗行為,保證modcount在疊代期間不變,否則抛出concurrentmodificationexception異常。
arraylist 的擴容,核心方法就是調用 arrays.copyof 方法,建立一個更大的數組,然後将原數組元素拷貝過去。
總結:
①當通過 arraylist() 構造一個空集合,初始長度是為0的,第1次添加元素,會建立一個長度為10的數組,并将該元素指派到數組的第一個位置。
②第2次添加元素,集合不為空,由于集合大小size + 1 < 數組的長度 10,是以直接添加元素到數組的第二個位置,不用擴容。
③第 11 次添加元素,此時 size+1 = 11 > 數組長度10。這時候建立一個長度為10+10*0.5 = 15 的數組(擴容1.5倍),然後将原數組元素引用拷貝到新數組。并将第 11 次添加的元素指派到新數組下标為10的位置。
④第 integer.max_value - 8 = 2147483639,然後 2147483639%1.5=1431655759(這個數是要進行擴容)次添加元素,為了防止溢出,此時會直接建立一個 1431655759 + 1 大小的數組,這樣一直,每次添加一個元素,都隻擴大一個範圍。
⑤第 integer.max_value - 7 次添加元素時,建立一個大小為 integer.max_value 的數組,在進行元素添加。
⑥第 integer.max_value + 1 次添加元素時,抛出 outofmemoryerror 異常。
源碼示例:将指定索引index處的元素修改。
源碼示例:很簡單,略
indexof(object o):傳回集合中第一次出現該元素的下标,沒有則傳回 -1。
lastindexof(object o):傳回集合中最後一次出現該元素的下标。沒有則傳回 -1。
傳回從 [fromindex, toindex) 的一個子串。但是注意,這裡隻是原集合的一個視圖。
想要獨立出來一個集合,解決辦法如下:
該方法用于回收多餘的記憶體。可以在确定集合不在添加多餘的元素之後,調用 trimtosize() 方法會将數組大小調整為集合元素的大小。
注意:該方法會花時間來複制數組元素,是以應該在确定不會添加元素之後在調用。
疊代器
注意:在進行 next() 方法調用的時候,會進行 checkforcomodification() 調用,該方法表示疊代器進行元素疊代時,如果同時進行增加和删除操作,會抛出 concurrentmodificationexception 異常。比如:
注意:疊代器隻能向後周遊,不能向前周遊,能夠删除元素,但是不能新增元素。
這是 list 集合特有的疊代器。可以一邊周遊,一邊新增或删除。
相比于 iterator 疊代器, listiterator 多出了能向前疊代,以及新增元素的功能。
listiterator
在arraylist類中,對上述接口的實作。
作者:craftsman-l