数据结构是算法的基础和计算机应用的基础,第一个实现的是动态数组,对应于Java的ArrayList,没有它做得那么好,但对于底层实现原理可以有一个初步掌握。以下是具体代码实现:

//此数组类支持泛型
 public class Array<E> {
  private E[] data; //声明保存数据的数组
  private int size;   //声明数组的大小即存储了多少个元素
  //有参构造函数需要提供数组初始容量,即数组能够装多少个元素
  public Array(int capacity) {
   data = (E[])new Object[capacity]; //根据参数开辟相应空间的数组
   size = 0;                         //初始大小为0
  }
  
  public Array() {                      //无参构造函数默认数组容量为10
   this(10);
  } public Array(E[] arr) {      //有参构造函数,以输入素组生成生成数组
   data = (E[])new Object[arr.length];
   for(int i = 0; i < arr.length; i++)
    data[i] = arr[i];
   size = arr.length;
  }
  
  //获取数组大小
  public int getSize() {
   return size;
  }
  //获取数组容量
  public int getCapacity() {
   return data.length;
  }
  //判断数组是否为空
  public boolean isEmpty() {
   return size == 0;
  }
  //添加元素,根据索引,将指定元素插到相应位置,支持动态添加
  public void add(int index, E e) {
   //判断索引合法性
   if(index < 0 || index > size)
    throw new IllegalArgumentException("Add failed.Require index >=0 and index <= size.");
   //如果数组尺寸等于数组容量,表明数组已满,需要扩容,大小为现在容量的2倍
   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++;                     //维护size,添加一个元素需要加1
  }
  //向数组末端添加一个元素
  public void addLast(E e) {
   add(size, e);
  }
  //向数组头部添加一个元素
  public void addFirst(E e) {
   add(0, e);
  }
  
  //根据索引获取元素
  public E get(int index) {
   if(index < 0 || index >=size)
    throw new IllegalArgumentException("Get failed.Index is illegal.");
   return data[index];
  }
  
  //根据索引修改元素值
  public void set(int index, E e) {
   if(index < 0 || index >=size)
    throw new IllegalArgumentException("Set failed.Index is illegal.");
   data[index] = e;
  }
  
  //判断数组中是否包含输入的元素
  public boolean contain(E e) {
   //遍历整个数组,判断数组中元素是否与输入元素相等
   for(int i = 0; i < size; i++) {
    if(data[i].equals(e))
     return true;
   }
   return false;
  }
  
  //根据输入元素查找下表值
  public int find(E e) {
   for(int i = 0; i < size; i++) {
    if(data[i].equals(e))
     return i;
   }
   return -1;
  }
  
  //根据索引删除相应元素
  public E remove(int index) {
   if(index < 0 || index >=size)
    throw new IllegalArgumentException("Remove failed.Index is illegal.");
   E ret = data[index];    //保存待删的元素
   //从需要删除的元素下一个开始遍历,元素往前挪一格
   for(int i = index + 1; i < size; i++) {
    data[i - 1] = data[i];
   }
   size--;                 //维护size,需要减一个
   data[size] = null;    
   
   //如果数组元素减少到容量的1/4,可以将数组容量缩减为容量1/2
   if(size == data.length / 4 && data.length /2 != 0) {
    resize(data.length / 2);
   }
   
   return ret;
  }
  //从头部删除元素
  public E removeFirst() {
   return remove(0);
  }
  //从末尾删除元素
  public E removeLast() {
   return remove(size - 1);
  }
  //根据相应的元素的值删除元素
  public void removeElement(E e) {
   int index = find(e);
   if(index != -1)
    remove(index);
  }
  //重写toStirng方法,方便观察
  @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();
  }
  //数组容量重整函数,此函数只需内部使用,外部不可见,将其私有
  private void resize(int newCapacity) {
   //根据传入容量申明新数组
   E[] newData = (E[]) new Object[newCapacity];
   //遍历数组将原数组元素保存到新数组中
   for(int i = 0; i < size; i++) {
    newData[i] = data[i];
   }
   //将原数组指向新数组,完成操作
   data = newData;
  } //交换数组中两个元素位置
  public void swap(int i, int j) {
   //判断索引合法性
   if(i < 0 || i >= size || j < 0 || j >= size)
    throw new IllegalArgumentException("Index is illegal.");
   //实施交换
   E temp = data[i];
   data[i] = data[j];
   data[j] = temp;
  }
 }

下面是测试程序

public class Main {
 public static void main(String[] args) {
   
   Array<Integer> arr = new Array<>();
   for(int i = 0; i < 10; i++) {
    arr.addLast(i);
   }
   System.out.println(arr);
   
   arr.add(1, 100);
   System.out.println(arr);
   
   arr.addFirst(-1);
   System.out.println(arr);
   
   arr.remove(2);
   System.out.println(arr);
   
   arr.removeElement(4);
   System.out.println(arr);
   
   arr.removeFirst();
   System.out.println(arr);
    }
  }

结果为:

Array: size = 10, capacity = 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array: size = 11, capacity = 20
[0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array: size = 12, capacity = 20
[-1, 0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array: size = 11, capacity = 20
[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array: size = 10, capacity = 20
[-1, 0, 1, 2, 3, 5, 6, 7, 8, 9]
Array: size = 9, capacity = 20
[0, 1, 2, 3, 5, 6, 7, 8, 9]

其他结果就不一一测试,能够实现ArrayList基本功能