ArrayList其實就那麼一回事兒之原始碼淺析
阿新 • • 發佈:2019-04-05
ArrayList 算是常用的集合之一了,不知作為javaner的你有沒在百忙之中抽出一點時間看看ArrayList的原始碼呢。 如果看了,你會覺得其實ArrayList其實就那麼一回事兒,對吧,下面就看看ArrayList的部分原始碼吧。
1 public class ArrayList<E> extends AbstractList<E> 2 implements List<E>, RandomAccess, Cloneable, java.io.Serializable 3 { 4 private static final long serialVersionUID = 8683452581122892189L; 5 6 //設定arrayList預設容量 7 private static final int DEFAULT_CAPACITY = 10; 8 9 //空陣列,當呼叫無引數建構函式的時候預設給個空陣列 10 private static final Object[] EMPTY_ELEMENTDATA = {}; 11 12 //這才是真正儲存資料的陣列 13 private transient Object[] elementData; 14 15 //arrayList的實際元素數量 16 private int size; 17 18 //構造方法傳入預設的capacity 設定預設陣列大小 19 public ArrayList(int initialCapacity) { 20 super(); 21 if (initialCapacity < 0) 22 throw new IllegalArgumentException("Illegal Capacity: "+ 23 initialCapacity); 24 this.elementData = new Object[initialCapacity]; 25 } 26 27 //無引數構造方法預設為空陣列 28 public ArrayList() { 29 super(); 30 this.elementData = EMPTY_ELEMENTDATA; 31 } 32 33 //構造方法傳入一個Collection, 則將Collection裡面的值copy到arrayList 34 public ArrayList(Collection<? extends E> c) { 35 elementData = c.toArray(); 36 size = elementData.length; 37 // c.toArray might (incorrectly) not return Object[] (see 6260652) 38 if (elementData.getClass() != Object[].class) 39 elementData = Arrays.copyOf(elementData, size, Object[].class); 40 } 41 42 //下面主要看看ArrayList 是如何將陣列進行動態擴充實現add 和 remove 43 44 45 public boolean add(E e) { 46 ensureCapacityInternal(size + 1); // Increments modCount!! 47 elementData[size++] = e; 48 return true; 49 } 50 51 52 public void add(int index, E element) { 53 rangeCheckForAdd(index); 54 55 ensureCapacityInternal(size + 1); // Increments modCount!! 56 System.arraycopy(elementData, index, elementData, index + 1, 57 size - index); 58 elementData[index] = element; 59 size++; 60 } 61 62 private void ensureCapacityInternal(int minCapacity) { 63 if (elementData == EMPTY_ELEMENTDATA) { 64 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); 65 } 66 67 ensureExplicitCapacity(minCapacity); 68 } 69 70 private void ensureExplicitCapacity(int minCapacity) { 71 modCount++; 72 73 //超出了陣列可容納的長度,需要進行動態擴充套件 74 if (minCapacity - elementData.length > 0) 75 grow(minCapacity); 76 } 77 78 //這才是動態擴充套件的精髓,看到這個方法,ArrayList瞬間被打回原形 79 private void grow(int minCapacity) { 80 int oldCapacity = elementData.length; 81 //設定新陣列的容量擴充套件為原來陣列的1.5倍 82 int newCapacity = oldCapacity + (oldCapacity >> 1); 83 //再判斷一下新陣列的容量夠不夠,夠了就直接使用這個長度建立新陣列, 84 //不夠就將陣列長度設定為需要的長度 85 if (newCapacity - minCapacity < 0) 86 newCapacity = minCapacity; 87 //判斷有沒超過最大限制 88 if (newCapacity - MAX_ARRAY_SIZE > 0) 89 newCapacity = hugeCapacity(minCapacity); 90 //將原來陣列的值copy新陣列中去, ArrayList的引用指向新陣列 91 //這兒會新建立陣列,如果資料量很大,重複的建立的陣列,那麼還是會影響效率, 92 //因此鼓勵在合適的時候通過構造方法指定預設的capaticy大小 93 elementData = Arrays.copyOf(elementData, newCapacity); 94 } 95 96 private static int hugeCapacity(int minCapacity) { 97 if (minCapacity < 0) // overflow 98 throw new OutOfMemoryError(); 99 return (minCapacity > MAX_ARRAY_SIZE) ? 100 Integer.MAX_VALUE : 101 MAX_ARRAY_SIZE; 102 } 103 104 105 }
其實, ArrayList 的本質就是陣列, ArrayList就是對陣列進行動態的擴充套件,其add, get , remove 等等操作就是對陣列的操作。至此,你還需要去記書籍上面所描述的ArrayList的特性了嘛? 如果還要記,那就弱爆了! ArrayList的一些特性都來源於陣列:有序、元素可重複、插入慢、 索引快 等等一系列神馬所謂的屬性, 你懂了麼?有木有