一個簡單的動態數組實現
基於數組實現 添加10w的容量 在刪除 所有 容量 平均是 0.4秒 這個效率是可觀的 下面來一起看看代碼
package com.array;import java.util.List;import java.util.Random;/** * * @author XiaoTian * @date 2018-08-08 *///基於動態數組的實現 E 是泛型//借用了一下 Java中的ArrayList的代碼//研究源碼也是一種樂趣//還能讓我們技術有所提高public class ArrayList<E> implements java.io.Serializable{/** * 初始容量 */ private static final int DEFAULT_CAPACITY = 10; /** * 用於空執行個體的共用空數組執行個體。 */ transient Object[] EMPTY_ELEMENTDATA = {}; /** * 數組緩衝區,其中儲存ArrayList的元素。 * ArrayList的容量是這個數組緩衝區的長度。 */ transient Object[] elementData; /** * 用於預設大小的空執行個體的共用空數組執行個體。 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * 大小 */ private int size; /** * 預設為空白 */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** * 自訂空間大小 * @param initialCapacity */ 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); } } public int size() {return size;} /** * 添加一個元素 元素位置是最後 * @param e */ public void add(E e) { ExtendElement(size + 1); this.elementData[size++] = e; } /** * 在頭部添加元素 * @param e */ public void addHead(E e) { this.elementData[0] = e; } /** * 擴充元素 */ private void ExtendElement(int size) { //容量 if(this.elementData.length == 0) { elementData = new Object[DEFAULT_CAPACITY]; }else if(this.elementData.length < size) { EMPTY_ELEMENTDATA = elementData; //擷取當前容量 int oldCapacity = elementData.length; //擴充容量 i + i >> 1 就是 i的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); elementData = new Object[newCapacity]; //1.源數組 2.源數組要複製的起始位置 3.目的數組 4.目的數組放置的起始位置 5.複製的長度 /** * 調用 System的靜態方法 arraycopy() 進行數組拷貝 * 標識為native意味JDK的本地庫 * 如果頻繁擴容會降低ArrayList的使用效能 * 賦值過程 */ System.arraycopy(EMPTY_ELEMENTDATA,0,elementData,0,size-1); } } /** * 刪除一個元素 */ public E remove(int index) { rangeCheck(index); E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) //index + 1 是當前 index 下一個 之 賦給 index 就全部替換了 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // 清楚地讓GC完成它的工作 //判斷容量是否是當前的1/4 是就 縮容 不要浪費不必要的記憶體空間 ShrinkageCapacity(); return oldValue; } /** * 刪除最後一個 * @return */ public E removeLast() { return remove(this.size - 1); } /** * 判斷是否大於size * @param index */ private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //輸出 Index 和 Size private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } /** * 擷取元素 * @param index * @return */ public E get(int index) { rangeCheck(index); return elementData(index); } /** * 查詢當前元素的值 * @param index * @return */ @SuppressWarnings("unchecked") E elementData(int index) { //擷取索引位置的元素 return (E) elementData[index]; } /** * 縮容 * @param args */ public void ShrinkageCapacity() { if(size == elementData.length / 4 && elementData.length / 2 != 0) { EMPTY_ELEMENTDATA = elementData; //縮二分之一 int oldCapacity = elementData.length / 2; elementData = new Object[oldCapacity]; System.arraycopy(EMPTY_ELEMENTDATA,0,elementData,0,size-1); } } //測試 public static void main(String[] args) { long then = System.currentTimeMillis();ArrayList<Integer> arrayList = new ArrayList<>();Random random = new Random();for (int i = 0; i < 100000; i++) {arrayList.add(random.nextInt());}for (int i = 0; i < 99999; i++) {arrayList.remove(0);}long now = System.currentTimeMillis();System.out.println("Elapsed time:" + (now - then)+" 毫秒"); }}
這是運行上面代碼的時間 每個人的機器不一樣啟動並執行效果也不一樣 僅供參考