Java集合框架:ArrayList擴容機制解釋
阿新 • • 發佈:2019-01-11
1、java中ArrayList該類的定義
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8683452581122892189L; /** * 預設容量為10 */ private static final int DEFAULT_CAPACITY = 10; /** * 空陣列:用於呼叫帶有容量切容量為0時初始化elementData這個值 */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * 空陣列:用於呼叫空構造時初始化elementData這個值 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** *陣列變數 */ transient Object[] elementData; // non-private to simplify nested class access /** * arrayList的長度 */ private int size; //後面自己需要看原始碼 ... }
2、ArrayList描述
ArrayList是一個繼承abstractList和實現List的介面的實現類。 ArrayList是以陣列實現的陣列佇列,允許重複。可以通過ArrayList來進行增加,刪除,修改,遍歷等操作。ArrayList可以說是一個動態陣列。動態的最好例子可以說就是ArrayList的底層是陣列,該陣列的長度可以根據實際需要不斷增加。
3、ArrayList的擴容機制
3.1 對外提供的檢查是否需要擴容方法
public void ensureCapacity(int minCapacity) { //判斷elementData是否是預設空陣列,如果不是minExpand為0,如果是minExpand=DEFAULT_CAPACITY=10 int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)? 0: DEFAULT_CAPACITY; //如果我們預測的值比陣列elementData陣列的長度實際要大,需要擴容。只能說明我們需要更大容器的列表。 if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } }
3.2 內部實現的擴容機制
private void ensureExplicitCapacity(int minCapacity) { modCount++;//父類AbstractLisy生命的屬性 // overflow-conscious code if (minCapacity - elementData.length > 0)//我們需要的長度比elementData的長度大,擴容 grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length;//獲取當前存放資料陣列的長度 int newCapacity = oldCapacity + (oldCapacity >> 1);//擴容到原來陣列長度的1.5倍 if (newCapacity - minCapacity < 0)//如果擴容到長度的1.5倍以後,仍然不夠用,直接將我們預計的值作為擴容長度 newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0)//擴容上限最大值為Integer的最大值-8,如果超過這個最大值,使用下面的方法 newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity);//使用陣列Arrays的copyOf()進行擴容,每次擴容都採用System.arrayCopy()複製到新陣列的 } private static int hugeCapacity(int minCapacity) {//如果擴容超過Integer.MAX_VALUE-8,程式碼會走該方法 if (minCapacity < 0) // overflow throw new OutOfMemoryError(); //如果我們預測的長度比Integer.MAX_VALUE-8大,最後取Integer.MAX_VALUE。 return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
4、ArrayList遍歷方式
List<String> testList = new ArrayList<String>();
testList.add("11");
testList.add("21");
testList.add("31");
testList.add("41");
testList.add("51");
testList.add("61");
testList.add("71");
/**
* for迴圈遍歷
*/
for(int index=0;index<testList.size();index++){
System.out.println(testList.get(index));
}
System.err.println("===========foreach===========");
/**
* foreach遍歷
*/
for(String index:testList){
System.out.println(index);
}
System.err.println("===========Iterator===========");
/**
* 迭代器Iterator
*/
Iterator<String> iterator = testList.iterator();
while(iterator.hasNext()){
System.err.println(iterator.next());
}
5、ArrayList和vector比較
普及:什麼是執行緒安全什麼是執行緒不安全
執行緒安全就是多執行緒訪問時,採用了加鎖機制,當一個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能進行訪問直到該執行緒讀取完,其他執行緒才可使用。不會出現資料不一致或者資料汙染。
執行緒不安全就是不提供資料訪問保護,有可能出現多個執行緒先後更改資料造成所得到的資料是髒資料。 如圖,List介面下面有兩個實現,一個是ArrayList,另外一個是vector。 從原始碼的角度來看,因為Vector的方法前加了,synchronized 關鍵字,也就是同步的意思,sun公司希望Vector是執行緒安全的,而希望arraylist是高效的,缺點就是另外的優點。
1、Vector每次擴容都是請求其大小的2倍空間,而ArrayList是1.5倍
2、Vector還有一個子類Stack