使用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)的,当免数组中元素个数处于扩缩容的临界位置,为了不复杂度震荡,缩容操做应当被设计成一个懒操做。数组