数组的长度在定义变量的时候便需要指定,并且只能是一个常数,不能是其它变量。所以,一旦定义了一个数组,系统将为它分配一个固定大小的空间,以后都不能改变,这样的数组称为静态数组。但在某些时候,我们需要的数组的长度是无法预先确定的,要解决这样的限制,就需要使用动态数组。
以下是我用java代码自己手动实现的动态数组的扩容和缩小。
数组类型使用泛型便于应对所有类型的数组
public class Array<E> {
private E[] data;
private int size;
//构造函数,传入数组的容量capacity构造Array
public Array(int capacity) {
data = (E[]) new Object[capacity];
size = 0;
}
然后在该类中添加add()方法,该方法是向数组中添加元素,但当数组容量已满时,则会调用resize()方法进行数组扩容.
public void add(int index,E e) {
if(index<0 || index>size)
throw new IllegalArgumentException("Add failed.Require index>=0 and index<=size");
//如果数组元素已满,则调用resize()方法进行数组扩容
if(size==data.length) {
resize(2*data.length);
}
/*因不确定index在数组索引中的位置,
所以添加时可能要将index后的元素后移将index空出来*/
for(int i=size-1;i>=index;i--)
data[i + 1] = data[i];
data[index] = e;
size ++;
}
既然有add()添加方法那么一定就有remove()删除方法,并且当删除后数组内元素要是容量不到该数组容量的一半,则调用resize()方法进行数组长度缩小.
// 从数组中删除index位置的元素, 返回删除的元素
public E remove(int index){
if(index<0 || index>=size)
throw new IllegalArgumentException("Remove failed. Index is illegal!");
//ret即为该删除的元素
E ret = data[index];
//因为删除了index位置上的元素,所以要将index后的元素前移
for(int i=index+1;i<size;i++) {
data[i-1] = data[i];
}
size--;
//因为data[size]处元素前移了,所以将该位置元素设置为空
data[size] = null;
if(size == data.length/2)
resize(data.length/2);
return ret;
}
最后就让我们来看看resize()函数是如何写的吧
private void resize(int newCapacity){
E[] newData = (E[]) new Object[newCapacity];
for(int i=0;i<size;i++) {
newData[i] = data[i];
}
data = newData;
}
以上就是构建一个简单的动态数组代码。