ArrayList原始碼分析
阿新 • • 發佈:2020-11-12
ArrayList原始碼分析
一隻java小白
最近學到集合,於是想分析一下ArrayList的原始碼。
-
預設長度是多少?
通過翻閱原始碼,發現是10
//預設長度是10 private static final int DEFAULT_CAPACITY = 10; //無引數構造器,這裡只初始化了一個數組(ArrayList通過陣列來儲存資料)。 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } //找到原始碼,發現是一個空的陣列,那麼長度是咋變成10的呢? private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
-
我此時發現了一句註釋:
* Any empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_CAPACITY when the first element is added.
所以該陣列的長度是在新增第一個資料時變成10的!!!下面來做個假設,於是我跟蹤add()方法
public boolean add(E e) { modCount++; //引數解釋: // e:形參,elementData:存放的資料,size:此時存放多個數據(預設是0) add(e, elementData, size); return true; } //繼續跟蹤,發現是在這個if語句中進行了擴容 private void add(E e, Object[] elementData, int s) { //陣列長度也是0,條件為true if (s == elementData.length) elementData = grow(); elementData[s] = e; size = s + 1; } private Object[] grow() { //實參變為1 return grow(size + 1); } private Object[] grow(int minCapacity) { int oldCapacity = elementData.length; //先不分析,這是建立ArrayList物件時指定長度或者第一次擴容之後再次擴容,才進到這裡 // if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //擴容為之前的1.5倍取整 int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, /* minimum growth */ oldCapacity >> 1 /* preferred growth */); // public static int newLength(int oldLength, int minGrowth, int prefGrowth) { // assert oldLength >= 0 // assert minGrowth > 0 // int newLength = Math.max(minGrowth, prefGrowth) + oldLength; // if (newLength - MAX_ARRAY_LENGTH <= 0) { // return newLength; // } // return hugeLength(oldLength, minGrowth); //} //賦值給新創建出的陣列,舊的陣列自動回收!!! return elementData = Arrays.copyOf(elementData, newCapacity); } else { //跳到這裡,都明白了,在10和size中取最大值,進行第一次擴容 return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)]; } }
-
Arrays.copyOf方法深究
//靜態泛型方法 public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { @SuppressWarnings("unchecked") //判斷newType是否是Object陣列 T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); //重點,複製陣列 //原陣列:original,目標陣列:copy //從original下標0開始將資料複製到copy陣列中,第一個資料放在下標0中,長度為 Math.min(original.length, newLength) System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }