實現:
1. 內部採用數組的方式。
1.1 添加元素,會每次校驗容量是否知足, 擴容規則是當前數組長度+當前數組長度的二分之一。容量上限是Integer.MAX_VALUE。 copy使用Arrays.copy的api
1.2 刪除元素
1.2.1 經過對象刪除。遍歷數組,刪除第一個匹配的對象
1.2.3 經過下標刪除。判斷下標是否越界。
使用 System.arraycopy進行copy, 並將元素的最後一位設置爲null.供gc回收
2. 內部是同步[modCount]
2.1 ArrayList數據結構變化的時候,都會將modCount++。
2.2 採用Iterator遍歷的元素, next()會去檢查集合是否被修改[checkForComodification],若是集合變動會拋出異常
相似於數據庫層面的 樂觀鎖 機制。 能夠經過 Iterator的api去刪除元素
3. 數組結構,內部存儲數據是有序的,而且數據能夠爲null,支持添加劇複數據
modCount做用:
https://www.cnblogs.com/zuochengsi-9/p/7050351.htmlhtml
package xin.rtime.collections.list; import java.util.Arrays; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.NoSuchElementException; // 模擬ArrayList的實現 public class ArrayList<E> { private transient int modCount = 0; // 修改次數 private transient Object[] elementData; // 數據集合 private static final Object[] EMPTY_ELEMENTDATA = {}; // 默認空數組 private int size; // 數組實際個數 private static final int DEFAULT_CAPACITY = 10; // 默認長度 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; // 數組最大長度 // 默認構造函數 public ArrayList() { elementData = EMPTY_ELEMENTDATA; // 默認等於空集合 } // 初始化指定長度 public ArrayList(int initialCapacity) { if (initialCapacity < 0) // 長度小於0 拋異常 throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); this.elementData = new Object[initialCapacity]; // new一個指定長度的對象數組 } // 添加元素 public boolean add(E e) { ensureCapacityInternal(size + 1); elementData[size++] = e; // 放置添加的元素 return true; } // 刪除元素 public boolean remove(E e) { if (e == 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 (e.equals(elementData[index])) { // eqals比較 fastRemove(index); return true; } } return false; } private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; // 當前size - index - 1 數組從0開始 if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); // system arraycopy elementData[--size] = null; // clear to let GC do its work gc回收 } public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; } // 獲取元素 public E get(int index) { rangeCheck(index); // index校驗 return elementData(index); } @SuppressWarnings("unchecked") E elementData(int index) { return (E) elementData[index]; } private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } // 返回元素個數 public int size() { return size; } // 判斷當前容量是否可否裝下元素 private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) // 空集合 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 10 傳入的 ensureExplicitCapacity(minCapacity); } // 提供外部遍歷 public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor; // index of next element to return 遊標 int lastRet = -1; // index of last element returned; -1 if no such 最後元素下標 int expectedModCount = modCount; // 當前數組修改次數 public boolean hasNext() { return cursor != size; // 當前遊標是否等於size } @SuppressWarnings("unchecked") public E next() { checkForComodification(); // 檢查數組是否被操做過 int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); // 檢查集合是否被操做過 try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } // 判斷容量 擴容 private void ensureExplicitCapacity(int minCapacity) { modCount++; // 修改+1 if (minCapacity - elementData.length > 0) // 當前長度 大於 數組長度 grow(minCapacity); } public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } private void rangeCheckForAdd(int index) { if (index > size || index < 0) // index 超出 size 或者 index 小於0 ---> 數組越界 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } public E set(int index, E element) { rangeCheck(index); // 校驗index是否知足 E oldValue = elementData(index); elementData[index] = element; return oldValue; } /** << : 左移運算符,num << 1,至關於num乘以2 >> : 右移運算符,num >> 1,至關於num除以2 >>> : 無符號右移,忽略符號位,空位都以0補齊 */ // 擴容 private void grow(int minCapacity) { int oldCapacity = elementData.length; // 當前數組長度 int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量大小 = 原來長度 + 原來長度 右移一位,除以2 if (newCapacity - minCapacity < 0) // 新長度 - 傳的長度 小於 0 newCapacity = minCapacity; // 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); // 拷貝原來數據 } // 判斷容量 private int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } }