1. ArrayList概述: 數組
ArrayList是List接口的可變數組的實現。實現了全部可選列表操做,並容許包括 null 在內的全部元素。除了實現 List 接口外,此類還提供一些方法來操做內部用來存儲列表的數組的大小。每一個ArrayList實例都有一個容量,該容量是指用來存儲列表元素的數組的大小。它老是至少等於列表的大小。隨着向ArrayList中不斷添加元素,其容量也自動增加。自動增加會帶來數據向新數組的從新拷貝,所以,若是可預知數據量的多少,可在構造ArrayList時指定其容量。在添加大量元素前,應用程序也可使用ensureCapacity操做來增長ArrayList實例的容量,這能夠減小遞增式再分配的數量。 注意,此實現不是同步的。若是多個線程同時訪問一個ArrayList實例,而其中至少一個線程從結構上修改了列表,那麼它必須保持外部同步。併發
2. ArrayList的實現: this
對於ArrayList而言,它實現List接口、底層使用數組保存全部元素。其操做基本上是對數組的操做。下面咱們來分析ArrayList的源代碼:spa
1) 底層使用數組實現:線程
1 private transient Object[] elementData;
2) 構造方法:
ArrayList提供了三種方式的構造器,能夠構造一個默認初始容量爲10的空列表、構造一個指定初始容量的空列表以及構造一個包含指定collection的元素的列表,這些元素按照該collection的迭代器返回它們的順序排列的。code
1 public ArrayList() { 2 this(10); 3 } 4 5 public ArrayList(int initialCapacity) { 6 super(); 7 if (initialCapacity < 0) 8 throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); 9 this.elementData = new Object[initialCapacity]; 10 } 11 12 public ArrayList(Collection<? extends E> c) { 13 elementData = c.toArray(); 14 size = elementData.length; 15 // c.toArray might (incorrectly) not return Object[] (see 6260652) 16 if (elementData.getClass() != Object[].class) 17 elementData = Arrays.copyOf(elementData, size, Object[].class); 18 }
// 用指定的元素替代此列表中指定位置上的元素,並返回之前位於該位置上的元素。 public E set(int index, E element) { RangeCheck(index); E oldValue = (E) elementData[index]; elementData[index] = element; return oldValue; }
// 將指定的元素添加到此列表的尾部。 public boolean add(E e) { ensureCapacity(size + 1); elementData[size++] = e; return true; }
// 將指定的元素插入此列表中的指定位置。 // 若是當前位置有元素,則向右移動當前位於該位置的元素以及全部後續元素(將其索引加1)。 public void add(int index, E element) { if (index > size || index < 0) throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size); // 若是數組長度不足,將進行擴容。 ensureCapacity(size+1); // Increments modCount!! // 將 elementData中從Index位置開始、長度爲size-index的元素, // 拷貝到從下標爲index+1位置開始的新的elementData數組中。 // 即將當前位於該位置的元素以及全部後續元素右移一個位置。 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; }
// 按照指定collection的迭代器所返回的元素順序,將該collection中的全部元素添加到此列表的尾部。 public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }
// 從指定的位置開始,將指定collection中的全部元素插入到此列表中。 public boolean addAll(int index, Collection<? extends E> c) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: " + index + ", Size: " + size); Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); // Increments modCount 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; }
4) 讀取:blog
// 返回此列表中指定位置上的元素。 public E get(int index) { RangeCheck(index); return (E) elementData[index]; }
// 移除此列表中指定位置上的元素。 public E remove(int index) { RangeCheck(index); modCount++; E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work return oldValue; }
// 移除此列表中首次出現的指定元素(若是存在)。這是應爲ArrayList中容許存放重複的元素。 public boolean remove(Object o) { // 因爲ArrayList中容許存放null,所以下面經過兩種狀況來分別處理。 if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { // 相似remove(int index),移除列表中指定位置上的元素。 fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; }
public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } }
public void trimToSize() { modCount++; int oldCapacity = elementData.length; if (size < oldCapacity) { elementData = Arrays.copyOf(elementData, size); } }
7) Fail-Fast機制:
ArrayList也採用了快速失敗的機制,經過記錄modCount參數來實現。在面對併發的修改時,迭代器很快就會徹底失敗,而不是冒着在未來某個不肯定時間發生任意不肯定行爲的風險。 索引