ArrayList集合
一、ArrayList的注意事項
ArrayList
集合可以加入null,並且可以加入多個ArrayList
是由陣列來實現的資料儲存的ArrayList
基本等同於Vetor
,但是ArrayList是執行緒不安全的(執行效率高),在多執行緒下不建議使用ArrayList
二、 ArrayList 的底層操作機制原始碼分析(重點,難點.)
1.JDK8.0
- ArrayList中存放了一個Object型別的陣列elementDate,什麼型別都能往裡面放
transient Object[] elementDate;
transient
,表示該屬性不會被序列化
- 當建立
ArrayList
物件時,如果使用的是無參構造器,則初始elementData
容量為0,第1次新增,則擴容elementData
為10,如需要再次擴容,則擴容elementData
為1.5倍 - 如果使用的是指定大小的構造器,則初始
elementData
容量為指定大小,如果需要擴容,則直接擴容elementData
為1.5倍。
注意:
- mount 表示的該陣列的修改次數
注意:
>>1
代表二進位制位向右移兩位,表示大小/2,這裡的int newCapacity = oldCapacity + (oldCapacity >> 1)
,代表擴容按舊陣列的1.5倍進行擴容(除第一次).newCapacity - minCapacity < 0
- 第一次擴容:
newCapacity = 0
,minCapacity = 10
,即當最小容量比新容量小的時候,把minCpacaity
賦給newCapacity
,只有第一次擴容會執行這個if- 如果newCapacity 比最大的大小還要大時
- 執行hugeCapacity這個方法
- 利用
copyOf
,把原陣列的內容拷貝到新陣列裡面去,並讓elementData指向該方法返回回來的地址,這樣可以在保留原來陣列中元素的同時,並增加新的空間,新空間預設為null;
- 第一次擴容:
若是使用指定大小的構造器
- 第一次擴容就按照elemenData的1.5倍擴容
- 整個執行流程還是和前面講的一樣
2.JDK11.0
使用ArrayList
無參構造器,會建立一個只讀的靜態的,型別為Object的空陣列
儲存資料底層實現原理:
- 呼叫add方法,引數:
e
為你要儲存的資料(大概). modCount
:為對該集合的操作次數,預設為0- 呼叫 add 方法(過載後的add方法)
- 當前元素個數 == 當前陣列長度,就會進行擴容
- 之後讓
elementData[s] = e
,s為當前元素個數,且讓size = s +1
;
- 之後讓
- 如果要進行擴容
- 返回一個擴容後的陣列,利用
copyOf
方法,把原來的陣列元素,拷貝到新陣列中,且新陣列的長度為原來陣列+1; - 然後在執行下面的賦值操作,同上
newCapacity方法
- 呼叫newCapacity,確定要擴大的空間
- oldCapacity 為當前陣列的長度
- newCapacity 為擴容後新陣列的長度:為舊陣列長度的1.5倍
如果新陣列的長度,比需要的(最小)容量小,則執行下面的程式碼
DEFAULT_CAPACITY
為int 型別 ,值為10,如果elementaData 為空陣列(DEFAULTCAPACTY_EMPTY_ELEMENTDATA),那麼就用把mincapacity和DEFAULT_CAPACITY傳進去進行比較,返回最大值,這個最大值就是要新陣列的容量- 如果minCapacity<0 則丟擲異常
- 並返回mincapacity
如果新陣列的長度,大於需要的(最小)容量,則執行下面的程式碼
- 三元表示式,這裡比較簡單不做闡述