集合是面試八股文之一,我今天開始就慢慢把這個集合類研究研究,主要從一些底層結構、使用方法和特性進行分析,沒有太多的分析原始碼,
1、基本屬性:
1 /**
2 * Default initial capacity.
3 * 默認初始容量大小
4 */
5 private static final int DEFAULT_CAPACITY = 10;
6
7 /**
8 * Shared empty array instance used for empty instances.
9 * 空陣列實體
10 */
11 private static final Object[] EMPTY_ELEMENTDATA =https://www.cnblogs.com/hellohmbb/p/ {};
12
13 /**
14 * Shared empty array instance used for default sized empty instances. We
15 * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
16 * first element is added.
17 * 默認容量的空陣列實體
18 */
19 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA =https://www.cnblogs.com/hellohmbb/p/ {};
20
21 /**
22 * The array buffer into which the elements of the ArrayList are stored.
23 * The capacity of the ArrayList is the length of this array buffer. Any
24 * empty ArrayList with elementData =https://www.cnblogs.com/hellohmbb/p/= DEFAULTCAPACITY_EMPTY_ELEMENTDATA
25 * will be expanded to DEFAULT_CAPACITY when the first element is added.
26 * 陣列元素物件、用于存放list中的元素
27 */
28 transient Object[] elementData; // non-private to simplify nested class access
29
30 /**
31 * The size of the ArrayList (the number of elements it contains).
32 * 添加的元素的數量
33 * @serial
34 */
35 private int size;
2、劃重點:
-
Arraylist的底層資料結構就是陣列,默認的初始容量是10,但是前提是你呼叫空建構式,沒有指定初始大小且第一次添加元素的情況下,會自動擴容為10,若沒有往里添加元素則還是0,如果有指定大小則以指定的為準,但是必須大于等于0,否則會拋出 IllegalArgumentException 例外提示 非法容量:xxx,
-
最小的擴容量是10,也就是第一次添加元素的時候會從0擴到10,直到添加第11個元素時才會呼叫grow方法,將當前陣列擴容至原來的1.5倍,
-
size 指的是陣列的實際元素個數,而不是陣列的大小
3、使用方法:
添加
1 arrayList.add( E element);
2 arrayList.add(int index, E element);
3 arrayList.addAll(Collection<? extends E> c);
洗掉
1 arrayList.remove(Object o);
2 arrayList.remove(int index)
3 arrayList.removeAll(Collection<?> c)
修改
1 arrayList.set(int index, E element)
查詢
1 arrayList.get(int index);
清空
1 arrayList.clear();
判斷是否存在
1 arrayList.contains(Object o); 2 arrayList.lastIndexOf(Object o);
4、特性:
1、有序、可重復
存入的Arraylsit的元素是有序的,且取出的時候可以按順序取出,且存入的元素是可以有重復的
2、查找快、添加洗掉慢
查找快是因為arraylist是動態陣列,長度可變,在記憶體中分配連續的空間,arraylist中的資料在記憶體中是連續的,查找的時候直接遍歷記憶體就可以,增刪慢是因為增加元素的時候,如果觸發了擴容機制,則需要對整個陣列進行復制,否則就是在陣列中間添加洗掉的話,也會導致后面的元素移動,影響效率,
3、執行緒不安全
1 public boolean add(E e) { 2 // 校驗是否擴容 3 ensureCapacityInternal(size + 1); // Increments modCount!! 4 elementData[size++] = e; 5 // 相當于 elementData[size] = e;size++; 6 return true; 7 }
假設此時size = 1,陣列長度為1;
第一就是資料錯誤的情況,
執行緒一, elementData[1] = 1;,時間片結束了,需要等待下一個時間片;
執行緒二, elementData[1] = 2;,時間片結束了,需要等待下一個時間片;
執行緒一 size++ size = 2
執行緒二 size++ size = 3
所以 elementData[1] 的原始值別覆寫了,而elementData[2] 的值卻賦值給了elementData[1] ,導致elementData[1] 的值不對,elementData[2]的值也不對且為空,
第二就是記憶體溢位的情況,
執行緒一,校驗容量通過,時間片結束了,需要等待下一個時間片;
執行緒二,校驗容量通過,時間片結束了,需要等待下一個時間片;
執行緒一,elementData[1] = 1 ,size++ ;( size = 2);
執行緒二,之前校驗容量通過了,所以沒有擴容,elementData[2] = 2,此時因為陣列長度為1,所以記憶體溢位,
我了解的大概就這些,也不是很全面,如有不足或者錯誤,歡迎指教,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/296199.html
標籤:其他
