使用java語言,基於java原生數組實現一個簡單的動態數組,具有基礎的擴容、縮容,並實現基礎的增、刪、改、查等功能。java
/** * 動態數組,java原生數組二次封裝 */ public class Array<E> { /** * 基於Java原生數組,保存數據的容器 */ private E[] data; /** * 當前元素個數 */ private int size; public Array(int capacity) { data = (E[]) new Object[capacity]; size = 0; } /** * 默認數組容量capacity=10 */ public Array() { this(10); } /** * 獲取數組中元素個數 * @return */ public int getSize() { return size; } /** * 獲取數組的容量 * @return */ public int getCapacity() { return data.length; } /** * 判斷數組是否爲空 * @return */ public boolean isEmpty() { return size == 0; } /** * 在全部元素後面添加新元素 * @param e 元素 */ public void addLast(E e) { add(size, e); } /** * 在全部元素前面添加新元素 * @param e 元素 */ public void addFirst(E e) { add(0, e); } /** * 向index索引位置插入一個新元素e * @param index 數組索引位置 * @param e 元素 */ public void add(int index, E e) { if (index < 0 || index > size) { throw new IllegalArgumentException("addList failed. index < 0 || index > size"); } //空間不足,擴容 if (size == data.length) { resize(2 * data.length); } for (int i = size - 1; i >= index; i--) { data[i + 1] = data[i]; } data[index] = e; size++; } /** * 根據元素索引獲取數組元素 * @param index 索引 * @return */ public E get(int index) { if (index < 0 || index >= size) { throw new IllegalArgumentException("get failed. index is illegal"); } return data[index]; } /** * 根據元素索引修改數組元素 * @param index 索引 * @param e 元素 * @return */ public void set(int index, E e) { if (index < 0 || index >= size) { throw new IllegalArgumentException("get failed. index is illegal"); } data[index] = e; } /** * 判斷包含元素 * @param e 元素 * @return */ public boolean contains(E e) { for (int i = 0; i < size; i++) { if (data[i].equals(e)) { return true; } } return false; } /** * 查找元素索引 * @param e 元素 * @return 返回元素索引,若是不存在則返回-1 */ public int find(E e) { for (int i = 0; i < size; i++) { if (data[i].equals(e)) { return i; } } return -1; } /** * 移除指定索引的元素 * @param index 索引 * @return 返回被移除的元素 */ public E remove(int index) { if (index < 0 || index >= size) { throw new IllegalArgumentException("get failed. index is illegal"); } E ret = data[index]; for (int i = index + 1; i < size; i++) { data[i - 1] = data[i]; } size--; data[size] = null; //空間利用率低,數組縮容,防止複雜度震盪 if (size == data.length / 4 && data.length / 2 != 0) { resize(data.length / 2); } return ret; } /** * 移除第一個元素 * @return 返回被移除元素 */ public E removeFirst() { return remove(0); } /** * 移除最後一個元素 * @return 返回被移除元素 */ public E removeLast() { return remove(size - 1); } /** * 移除數組中一個元素 * @param e 元素 */ public void removeElement(E e) { int index = find(e); if (index != -1) { remove(index); } } /** * 數組容器擴容、縮容 * @param newCapacity 新的容量 */ private void resize(int newCapacity) { E[] newData = (E[]) new Object[newCapacity]; for (int i = 0; i < size; i++) { newData[i] = data[i]; } data = newData; } @Override public String toString() { StringBuilder res = new StringBuilder(); res.append(String.format("Array: size = %d, capacity = %d\n", size, data.length)); res.append("["); for (int i = 0; i < size; i++) { res.append(data[i]); if (i != size - 1) { res.append(", "); } } res.append("]"); return res.toString(); } }
說明: 新增相關操做有可能會觸發擴容操做,而擴容操做是須要複製已有元素的,因此擴容自己的時間複雜度是O(n),新增相關操做的最壞複雜度是O(n)的segmentfault
說明: 刪除相關操做有可能會觸發縮容操做,而縮容操做是須要複製已有元素的,因此縮容自己的時間複雜度是O(n),新增相關操做的最壞複雜度是O(n)的,當免數組中元素個數處於擴縮容的臨界位置,爲了不復雜度震盪,縮容操做應當被設計成一個懶操做。數組