本篇隨筆主要描述的是我閱讀 arraylist 原始碼期間的對於 arraylist 的一些實現上的個人理解,有不對的地方,請指出~
先來看一下 arraylist 的繼承圖:
由圖可以看出,arraylist 的父類有 abstractlist、 abstractcollection ,所以我從 abstractcollection 類開始閱讀。
一、abstractcollection 類相關。
abstractcollection 類實現了 collection 介面,並且由於 abstractcollection 是乙個抽象類,所以它只實現了一些 collection 介面中的方法,例如 toarray() 方法, contains() 方法, remove() 方法等等。對於collection 介面中含有的其它方法仍令其保持抽象實現,我認為這樣實現的原因是 :抽象類的作用就是乙個概括作用,它需要將其子類中含有的公共方法在抽象類中加以實現,而抽象類中仍然保持抽象的方法一般都是每個子類有自己的實現,在抽象類中是沒有辦法統一起來的。
在 abstractcollection 類中,我以為 finishtoarray() 方法值得注意一下:
finishtoarray() 方法是用來給陣列 r 擴容的,每次當陣列 r 的容量不足以容納迭代器遍歷到的元素時,就會對陣列 r 進行擴容,並且對擴容後的陣列容量進行校驗(hugecapacity())。
擴容方法:newcap = cap + (cap >> 1)+ 1;
二、abstractlist 相關
abstractlist 也是乙個抽象類,其下面具體的子類主要有 linkedlist, arraylist, vector幾種。所以 abstractlist 中含有的方法主要是對這幾個具體的子類的抽象。
我認為 abstractlist 中主要有以下幾點值得注意:
1、abstractlist 中 iterator() 和 listiterator() 均採用內部類方式實現。
12、abstractlist 中 removerange() 方法為我們展示了如何運用迭代器移除 list 指定範圍的元素。(相比於 arraylist 中的 removerange 方法,用迭代器實現的 removerange 複雜度 較高)public iteratoriterator() 45
public listiteratorlistiterator() 89
public listiteratorlistiterator(final
intindex)
1415
private
class itr implements iterator
2021
private
class listitr extends itr implements listiterator
13、併發修改異常 concurrentmodificationexceptionprotected
void removerange(int fromindex, int
toindex)
7 }
在 abstractlist 中通過 expectedmodcount 和 modcount 兩個量比較來判斷是否產生了併發修改異常,當迭代器在迭代過程中發現 expectedmodcount 和 modcount 兩個量不相 等時就會丟擲併發修改異常。modcount 代表改動 list 的次數,當獲得乙個 iterator 或者 listiterator 時,就會將 modcount 值賦給 expectedmodcount,在迭代器使用的過程中,如果出 現兩個值不相等的情況 ,就證明有迭代器之外的操作改動了 list,而這很可能會導致迭代器對 list 的操作出現錯誤,所以在接下來使用迭代器的時候就會丟擲異常,這就是併發修改異 常的作用。
4、abstractlist 中的 sublist() 方法。
先來看下 sublist() 方法的實現:
public可見有 sublist 與 randomaccesssublist 兩種,區別在於是否實現 randomaccess 介面 ,也就是是否可以隨機讀取,例如 arraylist 可以隨機讀取,而 linkedlist 則只能順序讀 取。在sublist類的構造方法中,獲取了乙個 abstractlist 類的引用,作用是利用這個引用實現 sublist 中的相關方法。abstract
class abstractlistextends abstractcollectionimplements list
......
}class sublistextends abstractlist
public e set(int
index, e element)
......
}class randomaccesssublistextends sublistimplements
randomaccess
......
}
也就是說,sublist 幾乎所有方法都是基於 abstractlist 類實現的,對於 sublist 返回的 list 所做的所有改動都會反應到原來的 list 當中去。
三、arraylist 相關
我認為 arraylist 原始碼中以下幾點值得注意:
1、在 arraylist 把集合當做構造器中引數涉及到的 jdk bug,原始碼如下:
1在原始碼中可以看到由於 c.toarray might (incorrectly) not return object ,所以運用反射進行了 class 型別的判斷,那麼什麼時候會出現這種情況呢?下面舉例public arraylist(collection extends e>c)
說明:
1輸出結果為:public
static
void
main(string args)
可以看到 list 與 list1 的 toarray 方法返回的陣列型別是不相同的,如果嘗試向 string 型別陣列中插入其它型別元素,就會丟擲異常。所以
public arraylist(collection extends e> c) {} 方法中要對 collection.toarray() 方法返回的陣列型別進行判斷,如果不是 object,就要新建乙個 object,並進行複製。
2、arraylist 擴容方法
1採用 oldcapacity + (oldcapacity >> 1)來擴充容量。private
void grow(int
mincapacity)
3、與 abstractlist 相似,arraylist 的 sublist 方法也是基於 arraylist 實現的,對於 sublist 產生的 list 的所有操作都會反映到原來的 arraylist 上。
arraylist 原始碼相關就介紹到這裡。
JDK1 8原始碼閱讀(五) ArrayList
顧名思義,arraylist的結構實際就是乙個陣列。所以它的特性很明顯,插入乙個元素的時候,是耗時是乙個常量時間o 1 在插入n個元素的時候,需要的時間就是o n arraylist類圖設計 初始化預設容量 private static final int default capacity 10 空...
JDK1 8 二 Thread 原始碼閱讀筆記
這裡有的未知的就不貼出來了 private volatile char name 執行緒名稱 private int priority 執行緒優先順序 private boolean single step 是否單步執行 private boolean stillborn false 虛擬機器狀態 ...
Vector原始碼解析 jdk1 8
概述 vector實現了list的介面,底層同樣是基於陣列實現的,可以儲存null。功能結構與arraylist的類似,不同的是執行緒安全的。建構函式protected object elementdata protected int capacityincrement public vector ...