ArrayList原始碼解析

2022-03-03 21:07:56 字數 2052 閱讀 4407

一、arraylist認識

arraylist是可以動態增長和縮減的索引序列,它是基於陣列實現的list類。如圖

二、原始碼解析

內部儲存元素是陣列,預設資料大小是10,下面介紹常用方法。

2.1、構造方法

//第一種

public arraylist()

// 第二種

public arraylist(int initialcapacity) else if (initialcapacity == 0) else

}//第三種

public arraylist(collection extends e> c) else

}

2.2、增刪改查操作

對於增刪改查的基本操作,在這裡只給出一些比較重要的源**,實現起來比較簡單的就不給出了。

(1)增加元素

1

//第一種 尾插

2public

boolean

add(e e) 8//

第二種 插入

9public

void add(int

index, e element)

17//

第三種 批量增加

18public

boolean addall(collection extends e>c)

(2)刪除操作

1

//第一種

2public e remove(int

index)

16//

第二種17

public

boolean

remove(object o)

24 } else30}

31return

false

;32 }

(3)更改操作

1

public e set(int

index, e element)

(4)查操作

1

public

boolean

contains(object o)

4public

intindexof(object o) else

14return -1;

15 }

三、總結

1、arraylist 每次容器增長時,都是以1.5倍增長 

2、每次容器變化時需要將原陣列copy到新陣列中,使用的方法是系統native 方法  system.arraycopy(src,srcpos,dest,destpos,length)

3、盡量宣告時,預估好容器大小,以免多次容器大小的變化

4、執行緒不安全,陣列位置使用的是size標記

乙個 arraylist ,在新增乙個元素的時候,它可能會有兩步來完成: 

1. 在 items[size] 的位置存放此元素; 

2. 增大 size 的值。 

在單執行緒執行的情況下,如果 size = 0,新增乙個元素後,此元素在位置 0,而且 size=1; 

而如果是在多執行緒情況下,比如有兩個執行緒,執行緒 a 先將元素存放在位置 0。

但是此時 cpu 排程執行緒a暫停,執行緒 b 得到執行的機會。執行緒b也向此 arraylist 新增元素,因為此時 size 仍然等於 0

(注意,新增乙個元素是要兩個步驟,而執行緒a僅僅完成了步驟1),

所以執行緒b也將元素存放在位置0。然後執行緒a和執行緒b都繼續執行,都增加 size 的值。 

那好,現在我們來看看 arraylist 的情況,元素實際上只有乙個,存放在位置 0,而 size 卻等於 2。這就是「執行緒不安全」了。

5、捨棄效率使之變成執行緒安全的方法:使用synchronized關鍵字、collections.synchronizedlist();

ArrayList原始碼解析

new arraylist public arraylist public arraylist int initialcapacity else if initialcapacity 0 else private static final object defaultcapacity empty e...

ArrayList原始碼解析

arraylist內部的結構採用的是陣列。transient object elementdata non private to simplify nested class access當我們使用預設建構函式的時候,如下 private static final object defaultcapa...

ArrayList 原始碼解析

從日常 看arraylist的執行流程 第一步 我們初始化乙個 arraylist 然後新增乙個元素,如下 public class arraylisttest arraylist的建構函式和方法有三個,乙個是帶有初始大小的arraylist,乙個傳入collection,另外乙個空參。我們呼叫空參...