標籤:fast intern 源碼分析 出現 狀態 alt 技術分享 moved end
ArrayList概述
ArrayList是List介面最常用的實作類別,底層由數組實現,可存入null值,每個ArrayList都有一個容量(capacity)屬性,初始值是10,表示底層數組的儲存空間,容器內當前元素個數大於數組儲存容量時,ArrayList會自動完成容量擴增,因此我們在向ArrayList中添加元素時無需考慮容量,容器內部已經幫我們完成了容量擴容過程。
ArrayList具有public ArrayList() ;public ArrayList(int initialCapacity);public ArrayList(Collection<? extends E> c)三個構造器,建立ArrayList時可以指定容量或選擇用其他Collection為當前ArrayList賦值(底層採用數組複製的方式實現)或採用無參構造器建立預設容量的數組,size小於當前元素個數時,將自動完成容量擴充。
常用方法剖析
add方法
//添加元素至數組尾部 public boolean add(E e) { ensureCapacityInternal(size + 1); // 容量自增 elementData[size++] = e; return true; }//添加元素至制定位置(index) public void add(int index, E element) { rangeCheckForAdd(index);//檢查容量 ensureCapacityInternal(size + 1); // 容量自增 System.arraycopy(elementData, index, elementData, index + 1,size - index);//從index+1元素向後移動 elementData[index] = element;//為新添加元素賦值 size++; }//插入複雜度與位置與移動元素個數有關,此方法具有線性時間複雜度
addAll方法
//添加多個元素至數組尾部public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray();//待添加集合轉化為對象數組 int numNew = a.length; ensureCapacityInternal(size + numNew); // 擴充容量 System.arraycopy(a, 0, elementData, size, numNew);//數組複製 size += numNew; return numNew != 0; }//從指定位置添加多個元素 public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // 擴充容量 int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew,numMoved);//數組複製 System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }//添加過程不光與元素個數有關與待添加位置也有關
reomve方法
//從指定為主刪除元素並返回待刪除元素public E remove(int index) { rangeCheck(index);//檢查數組 modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index,numMoved);//數組向前移動 elementData[--size] = null; // 為GC方便回收,將末尾置為null return oldValue; }//刪除原數組中與目標對象相同的元素 public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; }
set/get方法
//為指定位置元素賦值 public E set(int index, E element) { rangeCheck(index);//檢查數組狀態 E oldValue = elementData(index);//檢查為否出現數組下標越界異常 elementData[index] = element;//用新值替換原元素值 return oldValue;//返回原元素值 }//擷取某一元素的值 public E get(int index) { rangeCheck(index);//檢查為否出現數組下標越界異常 return elementData(index);//返回索引位置的元素值 }
grow方法(實現自動容量擴充)
private void grow(int minCapacity) { int oldCapacity = elementData.length;//原容量 int newCapacity = oldCapacity + (oldCapacity >> 1);//擴充為原容量1.5倍 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity);//數組元素複製 }
Java ArrayList源碼分析