List原始碼解析之ArrayList原始碼分析

2021-08-11 06:25:37 字數 4523 閱讀 2503

arraylist是基於陣列實現的, 是乙個動態擴充套件的陣列,容量可自動增長。

arraylist是非執行緒安全的,只能在單執行緒環境下使用,多執行緒環境考慮使用collections.synchronizedlist(list list)函式返回乙個執行緒安全的arraylist類,也可以使用concurrent並發包下的copyonwritearraylist類。

arraylist實現了serializable介面,因此它支援序列化,能夠通過序列化傳輸,實現了randomaccess介面,支援快速隨機訪問,實際上就是通過下標序號進行快速訪問,實現了cloneable介面,能被轉殖。

private

static

final

int default_capacity = 10; // 預設初始值

transient object elementdata; // 存放資料的陣列

private

static

final object defaultcapacity_empty_elementdata = {}; // 存放的陣列預設容量10

protected

transient

int modcount = 0; // list被修改的次數

// 建構函式

/** * 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

*/public

arraylist(int initialcapacity) else

if (initialcapacity == 0) else

} /**

* constructs an empty list with an initial capacity of ten.

*/public

arraylist()

/** * 構造乙個包含指定collection 的元素的列表,這些元素按照

* 該collection 的迭代器返回它們的順序排列的

*/public

arraylist(collection extends e> c) else

}

set(int index, e element)
// 用指定的元素替代此列表中指定位置上的元素,並返回以前位於該位置上的元素    

public e set(int index, e element)

private

void

rangecheck(int index)

add(e e)
// 新增乙個元素到此列表的尾部 時間複雜度o(1),非常高效

public

boolean

add(e e)

// 如有必要,增加此 arraylist 例項的容量,以確保它至少能夠容納最小容量引數所指定的元素數

private

void

ensurecapacityinternal(int mincapacity)

ensureexplicitcapacity(mincapacity);

}private

void

ensureexplicitcapacity(int mincapacity)

// 增加容量,確保可容納元素

空間問題解決後,插入就變得容易了

// 將指定的元素新增到此列表中的指定位置

// 如果當前位置有元素,則向右移動當前位於該位置的元素以及所有後續元素(將其索引加1)

public

void

add(int index, e element)

private

void

rangecheckforadd(int index)

addall(collection
// 按照指定collection 的迭代器所返回的元素順序,將該collection 中的所有元素新增到此列表的尾部

public

boolean

addall(collection extends e> c)

addall(int index, collection
// 從指定的位置開始,將指定collection 中的所有元素插入到此列表中

public

boolean

addall(int index, collection extends e> c)

get(int index)
// 返回此列表中指定位置上的元素

public e get(int index)

e elementdata(int index)

根據下標和指定物件刪除,刪除時,被移除元素以後的所有元素向左移動乙個位置。

remove(int index)

// 刪除指定位置的元素,並返回刪除元素

public e remove(int index)

remove(object o)
// 移除此列表中首次出現的指定元素(如果存在)。這是應為arraylist 中允許存放重複的元素

public

boolean

remove(object o)

} else

}return

false;

}// 私有刪除方法,不進行越界檢測

private

void

fastremove(int index)

如果新增元素前已經**到了容量不足,可手動增加arraylist例項的容量,以減少遞增式再分配的數量。

ensurecapacity(int mincapacity)

public

void

ensurecapacity(int mincapacity)

}// 具體檢視ensureexplicitcapacity

在ensureexplicitcapacity中,可以看出,每次擴容時,會將老陣列中的元素重新拷貝乙份到新的陣列中(system.arraycopy()方法),每次陣列容量的增長大約是其原容量的1.5 倍。這種操作的代價是很高的,因此要盡量避免陣列容量擴容,使用時盡可能的指定容量,或者根據需求,通過呼叫ensurecapacity 方法來手動增加arraylist 例項的容量。

trimtosize()

該方法是將底層陣列的容量調整為當前列表儲存的實際元素的大小。

public

void

trimtosize()

}

通過迭代器遍歷
integer value = null;

iterator iter = list.iterator();

while (iter.hasnext())

隨機訪問,通過索引值去遍歷(推薦)
integer value = null;

int size = list.size();

for (int i=0; iforeach迴圈遍歷

integer value = null;

for (integer integ:list)

經測試,耗時:foreach迴圈 > 隨機 > 迭代器,優先使用迭代器方式 。

foreach的本質也是迭代器模式,可以反編譯檢視,而且還多了一步賦值操作,增加了開銷。

size(), isempty(), get(), set()方法均能在常數時間內完成,add()方法的時間開銷跟插入位置有關,addall()方法的時間開銷跟新增元素的個數成正比。其餘方法大都是線性時間。

java原始碼解析 List

an ordered collection 有序集合 list 的類資訊 public inte ce list extends collection collection 的類資訊 定義基本的method public inte ce collection extends iterable ite...

vue原始碼之Array

目錄 響應式具體實現 陣列子集和新增元素的追蹤 array中的問題 object通過setter改變屬性的值,所以我們利用getter時傳送依賴收集,在setter時觸發依賴更新,而且vue將資料轉換成響應式資料是在資料初始化時,對object中之後的屬性新增和刪除操作,無法做到自動更新,而是通過v...

Spring原始碼解析之 Aop原始碼解析(2)

spring aop 更多的是oop開發模式的乙個補充,幫助oop以更好的方式來解決對於需要解決業務功能模組之上統一管理 的功能 以一副圖來做為aop功能的說明更直觀些。對於類似系統的安全檢查,系統日誌,事務管理等相關功能,物件導向的開發方法並沒有更好的解決方法 aop引入了一些概念。更多的是spr...