## ä¸ å ä» ArrayList çæé 彿°è¯´èµ· **ArrayListæä¸ç§æ¹å¼æ¥åå§åï¼æé æ¹æ³æºç å¦ä¸ï¼** ```java /** * é»è®¤åå§å®¹éå¤§å° */ private static final int DEFAULT_CAPACITY = 10; private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** *é»è®¤æé 彿°ï¼ä½¿ç¨åå§å®¹é10æé ä¸ä¸ªç©ºå表(æ åæ°æé ) */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** * 带åå§å®¹éåæ°çæé 彿°ãï¼ç¨æ·èªå·±æå®å®¹éï¼ */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) {//åå§å®¹é大äº0 //å建initialCapacity大å°çæ°ç» this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) {//åå§å®¹éçäº0 //å建空æ°ç» this.elementData = EMPTY_ELEMENTDATA; } else {//åå§å®¹éå°äº0ï¼æåºå¼å¸¸ throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } /** *æé å 嫿å®collectionå ç´ çå表ï¼è¿äºå ç´ å©ç¨è¯¥éåçè¿ä»£å¨æé¡ºåºè¿å *妿æå®çéå为nullï¼throws NullPointerExceptionã */ public ArrayList(Collection extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } } ``` ç»å¿çåå¦ä¸å®ä¼åç° ï¼**以æ åæ°æé æ¹æ³å建 ArrayList æ¶ï¼å®é ä¸åå§åèµå¼çæ¯ä¸ä¸ªç©ºæ°ç»ãå½çæ£å¯¹æ°ç»è¿è¡æ·»å å ç´ æä½æ¶ï¼æçæ£åé 容éãå³åæ°ç»ä¸æ·»å 第ä¸ä¸ªå ç´ æ¶ï¼æ°ç»å®¹éæ©ä¸º10ã** ä¸é¢å¨æä»¬åæ ArrayList æ©å®¹æ¶ä¼è®²å°è¿ä¸ç¹å å®¹ï¼ ## äº ä¸æ¥ä¸æ¥åæ ArrayList æ©å®¹æºå¶ è¿é以æ åæé 彿°å建ç ArrayList 为ä¾åæ ### 1. å æ¥ç `add` æ¹æ³ ```java /** * å°æå®çå ç´ è¿½å å°æ¤åè¡¨çæ«å°¾ã */ public boolean add(E e) { //æ·»å å ç´ ä¹åï¼å è°ç¨ensureCapacityInternalæ¹æ³ ensureCapacityInternal(size + 1); // Increments modCount!! //è¿éçå°ArrayListæ·»å å ç´ çå®è´¨å°±ç¸å½äºä¸ºæ°ç»èµå¼ elementData[size++] = e; return true; } ``` ### 2. 忥çç `ensureCapacityInternal()` æ¹æ³ å¯ä»¥çå° `add` æ¹æ³ é¦å è°ç¨äº`ensureCapacityInternal(size + 1)` ```java //å¾å°æå°æ©å®¹é private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // è·åé»è®¤ç容éåä¼ å ¥åæ°çè¾å¤§å¼ minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } ``` **å½ è¦ add è¿ç¬¬1个å ç´ æ¶ï¼minCapacity为1ï¼å¨Math.max()æ¹æ³æ¯è¾åï¼minCapacity 为10ã** ### 3. `ensureExplicitCapacity()` æ¹æ³ 妿è°ç¨ `ensureCapacityInternal()` æ¹æ³å°±ä¸å®ä¼è¿è¿ï¼æ§è¡ï¼è¿ä¸ªæ¹æ³ï¼ä¸é¢æä»¬æ¥ç ç©¶ä¸ä¸è¿ä¸ªæ¹æ³çæºç ï¼ ```java //夿æ¯å¦éè¦æ©å®¹ private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) //è°ç¨growæ¹æ³è¿è¡æ©å®¹ï¼è°ç¨æ¤æ¹æ³ä»£è¡¨å·²ç»å¼å§æ©å®¹äº grow(minCapacity); } ``` æä»¬æ¥ä»ç»åæä¸ä¸ï¼ - å½æä»¬è¦ add è¿ç¬¬1个å ç´ å° ArrayList æ¶ï¼elementData.length 为0 ï¼å ä¸ºè¿æ¯ä¸ä¸ªç©ºç listï¼ï¼å 为æ§è¡äº `ensureCapacityInternal()` æ¹æ³ ï¼æä»¥ minCapacity æ¤æ¶ä¸º10ãæ¤æ¶ï¼`minCapacity - elementData.length > 0 `æç«ï¼æä»¥ä¼è¿å ¥ `grow(minCapacity)` æ¹æ³ã - å½add第2个å ç´ æ¶ï¼minCapacity 为2ï¼æ¤æ¶e lementData.length(容é)卿·»å 第ä¸ä¸ªå ç´ åæ©å®¹æ 10 äºãæ¤æ¶ï¼`minCapacity - elementData.length > 0 ` 䏿ç«ï¼æä»¥ä¸ä¼è¿å ¥ ï¼æ§è¡ï¼`grow(minCapacity)` æ¹æ³ã - æ·»å 第3ã4···å°ç¬¬10个å ç´ æ¶ï¼ä¾ç¶ä¸ä¼æ§è¡growæ¹æ³ï¼æ°ç»å®¹éé½ä¸º10ã ç´å°æ·»å 第11个å ç´ ï¼minCapacity(为11)æ¯elementData.lengthï¼ä¸º10ï¼è¦å¤§ãè¿å ¥growæ¹æ³è¿è¡æ©å®¹ã ### 4. `grow()` æ¹æ³ ```java /** * è¦åé çæå¤§æ°ç»å¤§å° */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; /** * ArrayListæ©å®¹çæ ¸å¿æ¹æ³ã */ private void grow(int minCapacity) { // oldCapacity为æ§å®¹éï¼newCapacity为æ°å®¹é int oldCapacity = elementData.length; //å°oldCapacity å³ç§»ä¸ä½ï¼å ¶ææç¸å½äºoldCapacity /2ï¼ //æä»¬ç¥éä½è¿ç®çé度è¿è¿å¿«äºæ´é¤è¿ç®ï¼æ´å¥è¿ç®å¼çç»æå°±æ¯å°æ°å®¹éæ´æ°ä¸ºæ§å®¹éç1.5åï¼ int newCapacity = oldCapacity + (oldCapacity >> 1); //ç¶åæ£æ¥æ°å®¹éæ¯å¦å¤§äºæå°éè¦å®¹éï¼è¥è¿æ¯å°äºæå°éè¦å®¹éï¼é£ä¹å°±ææå°éè¦å®¹éå½ä½æ°ç»çæ°å®¹éï¼ if (newCapacity - minCapacity < 0) newCapacity = minCapacity; // 妿æ°å®¹éå¤§äº MAX_ARRAY_SIZE,è¿å ¥(æ§è¡) `hugeCapacity()` æ¹æ³æ¥æ¯è¾ minCapacity å MAX_ARRAY_SIZEï¼ //妿minCapacityå¤§äºæå¤§å®¹éï¼åæ°å®¹éå为`Integer.MAX_VALUE`ï¼å¦åï¼æ°å®¹é大å°å为 MAX_ARRAY_SIZE å³ä¸º `Integer.MAX_VALUE - 8`ã if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } ``` **int newCapacity = oldCapacity + (oldCapacity >> 1),æä»¥ ArrayList æ¯æ¬¡æ©å®¹ä¹å容éé½ä¼åä¸ºåæ¥ç 1.5 åï¼** è®°æ¸ æ¥äºï¼ä¸æ¯ç½ä¸å¾å¤äººè¯´ç 1.5 å+1ï¼ > ">>"ï¼ç§»ä½è¿ç®ç¬¦ï¼ï¼>>1 å³ç§»ä¸ä½ç¸å½äºé¤2ï¼å³ç§»nä½ç¸å½äºé¤ä»¥ 2 ç n 次æ¹ãè¿é oldCapacity ææ¾å³ç§»äº1使以ç¸å½äºoldCapacity /2ã对äºå¤§æ°æ®ç2è¿å¶è¿ç®,ä½ç§»è¿ç®ç¬¦æ¯é£äºæ®éè¿ç®ç¬¦çè¿ç®è¦å¿«å¾å¤,å 为ç¨åºä» ä» ç§»å¨ä¸ä¸èå·²,ä¸å»è®¡ç®,è¿æ ·æé«äºæç,èçäºèµæº ã **æä»¬åæ¥éè¿ä¾åæ¢ç©¶ä¸ä¸`grow()` æ¹æ³ ï¼** - å½add第1个å ç´ æ¶ï¼oldCapacity 为0ï¼ç»æ¯è¾å第ä¸ä¸ªif夿æç«ï¼newCapacity = minCapacity(为10)ã使¯ç¬¬äºä¸ªif夿ä¸ä¼æç«ï¼å³newCapacity 䏿¯ MAX_ARRAY_SIZE大ï¼åä¸ä¼è¿å ¥ `hugeCapacity` æ¹æ³ãæ°ç»å®¹é为10ï¼addæ¹æ³ä¸ return true,sizeå¢ä¸º1ã - å½add第11个å ç´ è¿å ¥growæ¹æ³æ¶ï¼newCapacity为15ï¼æ¯minCapacityï¼ä¸º11ï¼å¤§ï¼ç¬¬ä¸ä¸ªif夿䏿ç«ãæ°å®¹é没æå¤§äºæ°ç»æå¤§sizeï¼ä¸ä¼è¿å ¥hugeCapacityæ¹æ³ãæ°ç»å®¹éæ©ä¸º15ï¼addæ¹æ³ä¸return true,sizeå¢ä¸º11ã - 以æ¤ç±»æ¨Â·Â·Â·Â·Â·Â· **è¿éè¡¥å ä¸ç¹æ¯è¾éè¦ï¼ä½æ¯å®¹æè¢«å¿½è§æçç¥è¯ç¹ï¼** - java ä¸ç `length `屿§æ¯é对æ°ç»è¯´ç,æ¯å¦è¯´ä½ 声æäºä¸ä¸ªæ°ç»,æ³ç¥éè¿ä¸ªæ°ç»çé¿åº¦åç¨å°äº length è¿ä¸ªå±æ§. - java ä¸ç `length()` æ¹æ³æ¯é对å符串说ç,妿æ³çè¿ä¸ªå符串çé¿åº¦åç¨å° `length()` è¿ä¸ªæ¹æ³. - java ä¸ç `size()` æ¹æ³æ¯é对æ³åéå说ç,妿æ³çè¿ä¸ªæ³åæå¤å°ä¸ªå ç´ ,å°±è°ç¨æ¤æ¹æ³æ¥æ¥ç! ### 5. `hugeCapacity()` æ¹æ³ã ä»ä¸é¢ `grow()` æ¹æ³æºç æä»¬ç¥éï¼ å¦ææ°å®¹éå¤§äº MAX_ARRAY_SIZE,è¿å ¥(æ§è¡) `hugeCapacity()` æ¹æ³æ¥æ¯è¾ minCapacity å MAX_ARRAY_SIZEï¼å¦æminCapacityå¤§äºæå¤§å®¹éï¼åæ°å®¹éå为`Integer.MAX_VALUE`ï¼å¦åï¼æ°å®¹é大å°å为 MAX_ARRAY_SIZE å³ä¸º `Integer.MAX_VALUE - 8`ã ```java private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); //对minCapacityåMAX_ARRAY_SIZEè¿è¡æ¯è¾ //è¥minCapacity大ï¼å°Integer.MAX_VALUEä½ä¸ºæ°æ°ç»çå¤§å° //è¥MAX_ARRAY_SIZE大ï¼å°MAX_ARRAY_SIZEä½ä¸ºæ°æ°ç»çå¤§å° //MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } ``` ## ä¸ `System.arraycopy()` å `Arrays.copyOf()`æ¹æ³ é 读æºç çè¯ï¼æä»¬å°±ä¼åç° ArrayList ä¸å¤§éè°ç¨äºè¿ä¸¤ä¸ªæ¹æ³ãæ¯å¦ï¼æä»¬ä¸é¢è®²çæ©å®¹æä½ä»¥å`add(int index, E element)`ã`toArray()` çæ¹æ³ä¸é½ç¨å°äºè¯¥æ¹æ³ï¼ ### 3.1 `System.arraycopy()` æ¹æ³ ```java /** * 卿¤å表ä¸çæå®ä½ç½®æå ¥æå®çå ç´ ã *å è°ç¨ rangeCheckForAdd 对indexè¿è¡ç鿣æ¥ï¼ç¶åè°ç¨ ensureCapacityInternal æ¹æ³ä¿è¯capacityè¶³å¤å¤§ï¼ *åå°ä»indexå¼å§ä¹åçæææååç§»ä¸ä¸ªä½ç½®ï¼å°elementæå ¥indexä½ç½®ï¼æåsizeå 1ã */ public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! //arraycopy()æ¹æ³å®ç°æ°ç»èªå·±å¤å¶èªå·± //elementData:æºæ°ç»;index:æºæ°ç»ä¸çèµ·å§ä½ç½®;elementDataï¼ç®æ æ°ç»ï¼index + 1ï¼ç®æ æ°ç»ä¸çèµ·å§ä½ç½®ï¼ size - indexï¼è¦å¤å¶çæ°ç»å ç´ çæ°éï¼ System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } ``` æä»¬åä¸ä¸ªç®åçæ¹æ³æµè¯ä»¥ä¸ï¼ ```java public class ArraycopyTest { public static void main(String[] args) { // TODO Auto-generated method stub int[] a = new int[10]; a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3; System.arraycopy(a, 2, a, 3, 3); a[2]=99; for (int i = 0; i < a.length; i++) { System.out.println(a[i]); } } } ``` ç»æï¼ ``` 0 1 99 2 3 0 0 0 0 0 ``` ### 3.2 `Arrays.copyOf()`æ¹æ³ ```java /** 以æ£ç¡®ç顺åºè¿åä¸ä¸ªå 嫿¤åè¡¨ä¸ææå ç´ çæ°ç»ï¼ä»ç¬¬ä¸ä¸ªå°æåä¸ä¸ªå ç´ ï¼; è¿åçæ°ç»çè¿è¡æ¶ç±»åæ¯æå®æ°ç»çè¿è¡æ¶ç±»åã */ public Object[] toArray() { //elementDataï¼è¦å¤å¶çæ°ç»ï¼sizeï¼è¦å¤å¶çé¿åº¦ return Arrays.copyOf(elementData, size); } ``` 个人è§å¾ä½¿ç¨ `Arrays.copyOf()`æ¹æ³ä¸»è¦æ¯ä¸ºäºç»åææ°ç»æ©å®¹ï¼æµè¯ä»£ç å¦ä¸ï¼ ```java public class ArrayscopyOfTest { public static void main(String[] args) { int[] a = new int[3]; a[0] = 0; a[1] = 1; a[2] = 2; int[] b = Arrays.copyOf(a, 10); System.out.println("b.length"+b.length); } } ``` ç»æï¼ ``` 10 ``` ### 3.3 两è èç³»ååºå« **èç³»ï¼** çä¸¤è æºä»£ç å¯ä»¥åç° copyOf() å é¨å®é è°ç¨äº `System.arraycopy()` æ¹æ³ **åºå«ï¼** `arraycopy()` éè¦ç®æ æ°ç»ï¼å°åæ°ç»æ·è´å°ä½ èªå·±å®ä¹çæ°ç»éæè åæ°ç»ï¼èä¸å¯ä»¥éæ©æ·è´çèµ·ç¹åé¿åº¦ä»¥åæ¾å ¥æ°æ°ç»ä¸çä½ç½® `copyOf()` æ¯ç³»ç»èªå¨å¨å 鍿°å»ºä¸ä¸ªæ°ç»ï¼å¹¶è¿å该æ°ç»ã ## å `ensureCapacity`æ¹æ³ ArrayList æºç 䏿ä¸ä¸ª `ensureCapacity` æ¹æ³ä¸ç¥é大家注æå°æ²¡æï¼è¿ä¸ªæ¹æ³ ArrayList å 鍿²¡æè¢«è°ç¨è¿ï¼æä»¥å¾æ¾ç¶æ¯æä¾ç»ç¨æ·è°ç¨çï¼é£ä¹è¿ä¸ªæ¹æ³æä»ä¹ä½ç¨å¢ï¼ ```java /** å¦æå¿ è¦ï¼å¢å æ¤ ArrayList å®ä¾ç容éï¼ä»¥ç¡®ä¿å®è³å°å¯ä»¥å®¹çº³ç±minimum capacityåæ°æå®çå ç´ æ°ã * * @param minCapacity æéçæå°å®¹é */ public void ensureCapacity(int minCapacity) { int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // any size if not default element table ? 0 // larger than default for default empty table. It's already // supposed to be at default size. : DEFAULT_CAPACITY; if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } } ``` **æå¥½å¨ add 大éå ç´ ä¹åç¨ `ensureCapacity` æ¹æ³ï¼ä»¥åå°å¢ééæ°åé çæ¬¡æ°** æä»¬éè¿ä¸é¢ç代ç å®é æµè¯ä»¥ä¸è¿ä¸ªæ¹æ³çææï¼ ```java public class EnsureCapacityTest { public static void main(String[] args) { ArrayList