ArrayList隨機訪問,動態擴容

2021-08-20 20:37:14 字數 1682 閱讀 2751

隨機訪問:

arraylist是乙個動態陣列,實現了randomaccess介面,支援隨機訪問,通過get(i)即可獲得相應記憶體中存放的值。原因是因為arraylist存放的內容在記憶體中是連續的,陣列直接用[ ]訪問,相當於直接操作記憶體位址,所以隨機訪問的效率較高。

普通的for迴圈是隨機訪問的,所以遍歷arraylist使用普通for迴圈比增強for迴圈和迭代器的效率高。

而linkedlist是乙個雙向鍊錶,鍊錶只能順序訪問,linkedlist中的get方法是按照順序從列表的一端開始檢查,直到找到要找的位址。所以遍歷linkedlist使用增強for迴圈和迭代器的效率高,使用普通for迴圈會每次都從頭開始遍歷,效率較差。

動態擴容:

arraylist是動態擴容的,建立arraylist時,arraylist有三個建構函式:

public arraylist();
預設的構造器,將會以預設的大小來初始化內部的陣列 。

public arraylist(collection<? extends e> c)
用乙個icollection物件來構造,並將該集合的元素新增到arraylist。

public arraylist(int initialcapacity)
用指定的大小來初始化內部的陣列。

對於預設的構造方法,在沒指定initialcapacity時就是會使用延遲分配物件陣列空間,開始時不分配空間,當第一次插入元素時才分配10(預設)個物件空間,當10個空間儲存完了,插入第11個時,空間會通過位運算擴容到原來的1.5倍,即變為15個空間。再插入第16個元素時,又會擴容到原來的1.5倍,以此擴容。

擴容是通過grow()方法實現的,原始碼:

/*

*增加容量,以確保它至少能容納

*由最小容量引數指定的元素數。

* @param mincapacity所需的最小容量

*/private void grow(int mincapacity)

可以看到,最後求得擴容後新的空間,是通過arrays.copyof()方法,copyof()方法的原始碼:

public static int copyof(int original, int newlength)
可以看到,在方法內部新建立了乙個陣列,然後將原來陣列的內容複製進去,返回新陣列的引用。新擴容的空間中存放的為陣列初始化的預設值,當通過add()方法向arraylist中加入元素時,會覆蓋掉原來的預設值。

這樣的擴容方法會浪費一定的空間,可以呼叫trimsize方法,這個方法用於將arraylist固定到實際元素的大小,當動態陣列元素確定不在新增的時候,可以呼叫這個方法來釋放空餘的記憶體。

擴容的時間是在add()方法空間不夠時,add方法的原始碼:

public boolean add(e e)
當add()容量夠時,就是直接在後面新增,速度很快。當add()容量不夠時,就將新建乙個更大的陣列,然後把舊陣列的內容複製過去。當在中間位置插入時,會把插入點及後面的資料後移乙個位置。然後插入。當在中間位置刪除時,會將刪除點後面的資料前移乙個位置。所以說任何時間點,其記憶體都是連續的,隨機索引訪問效率很高。插入,刪除效率低。或者容量滿時add()效率低。

隨機訪問 順序訪問

讓隨機變成順序 技術思想 訪問結構 分為隨機訪問和非隨機訪問 又稱順序訪問 1 隨機訪問就是直接訪問,可以通過下標直接訪問的那種資料結構,與儲存位置無關,例如陣列。非隨機訪問 就是順序訪問了,不能通過下標訪問了,只能按照儲存順序訪問,與儲存位置有關,例如鍊錶。2 順序訪問就是訪問第n個資料時,必須先...

ArrayList動態擴容機制

初始化 有三種方式預設的構造器,將會以預設的大小來初始化內部的陣列 public arraylist 用乙個icollection物件來構造,並將該集合的元素新增到arraylist public arraylist collection c 用指定的大小來初始化內部的陣列 public array...

Arraylist動態擴容詳解

arraylist是基於陣列實現的,是乙個動態陣列,其容量能自動增長。arraylist不是執行緒安全的,只能用在單執行緒環境下。實現了serializable介面,因此它支援序列化,能夠通過序列化傳輸 實現了randomaccess介面,支援快速隨機訪問,實際上就是通過下標序號進行快速訪問 實現了...