ArrayList的數據結構java
ArrayList是一種線性數據結構,底層是動態數組實現的,與java中的數組相比,它的容量能夠動態添加。數組
ArrayList的類結構數據結構
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ ...... }
ArrayList的主要成員變量dom
//默認容量 private static final int DEFAULT_CAPACITY = 10; private static final Object[] EMPTY_ELEMENTDATA = {}; private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //ArrayList存儲數據的數組 transient Object[] elementData; //存儲元素數目 private int size; //默認最大容量數目 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; // protected transient int modCount = 0;
ArrayList的構造方法this
public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
ArrayList的主要方法code
存:ci
boolean add(E e);element
public boolean add(E e) { //根據當前下角標size+1和當前數組的容量,判斷是否須要擴容,若是須要,擴容到1.5倍 ensureCapacityInternal(size + 1); // Increments modCount!! //將新元素加入數組中,下角標爲size+1 elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //若是存儲元素的數組爲空,容量值爲10和minCapacity中的較大者 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { //更新次數加一 modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) //若是minCapacity大於當前數組的長度,擴容 grow(minCapacity); } private void grow(int minCapacity) { //將當前數組的長度賦值給oldCapacity int oldCapacity = elementData.length; //新的容量值爲原來的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) //若是新容量值比minCapacity 值小,新容量值即爲minCapacity newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) //若是新容量值大於容許的最大長度 newCapacity = hugeCapacity(minCapacity); //根據容量建立一個新數組,並將舊數組的元素複製給新數組 elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow //若是minCapacity小於零,直接拋出OOM異常 throw new OutOfMemoryError(); //若是minCapacity大於最大數組容量,則返回Integer的最大值,不然返回 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
void add(int index,E e);rem
public void add(int index, E element) { //校驗下角標index是否越界 rangeCheckForAdd(index); //判斷是否須要擴容 ensureCapacityInternal(size + 1); // Increments modCount!! //將當前數組中下角標爲[index,size]的元素複製到[index+1,size+1]的位置 System.arraycopy(elementData, index, elementData, index + 1, size - index); //將element放置到數組下角標爲index的位置 elementData[index] = element; //數組內元素個數加1 size++; } private void rangeCheckForAdd(int index) { if (index > size || index < 0) //若是index大於數組元素的個數,或者index<0,拋出下角標越界異常 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
E set(int index,E e);get
public E set(int index, E element) { //校驗下角標是否越界 rangeCheck(index); //將數組中下角標爲index的元素賦值給oldValue E oldValue = elementData(index); //再將新元素放置到下角標index位置 elementData[index] = element; //返回舊值 return oldValue; }
取:
E get(int index);
public E get(int index) { //校驗下角標是否越界 rangeCheck(index); //返回數組中下角標爲index的元素 return elementData(index); } private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
移除:
E remove(int index);經過下角標移除。
public E remove(int index) { //判斷下角標是否越界 rangeCheck(index); //修改次數加一 modCount++; //將數組中下角標爲index的元素賦值給oldValue E oldValue = elementData(index); //要移動的元素個數 int numMoved = size - index - 1; if (numMoved > 0) //若是要移動的元素個數大於0,移動 // 將elementData數組index+1位置開始拷貝到elementData從index開始的空間 System.arraycopy(elementData, index+1, elementData, index, numMoved); //最後一個元素設爲null,並將size-1 elementData[--size] = null; // clear to let GC do its work 返回舊值 return oldValue; }
boolean remove(Object o);移除指定元素
public boolean remove(Object o) { if (o == null) { //若是要移除的元素爲null //循環遍歷數組 for (int index = 0; index < size; index++) if (elementData[index] == null) { //若是某個下角標的元素爲null //移除該下角標的元素 fastRemove(index); return true; } } else { //循環遍歷數組 for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { //若是某個下角標的元素爲o ////移除該下角標的元素 fastRemove(index); return true; } } return false; } private void fastRemove(int index) { //修改次數加一 modCount++; //要移動的元素個數 int numMoved = size - index - 1; if (numMoved > 0) // 將elementData數組index+1位置開始拷貝到elementData從index開始的空間 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }