接上一篇,自己完成了整个数组类的各种基本方法如:增删改查,这还不够,还可以使用泛型优化一下,让数组不仅仅可以存储整数值,还可以存储其他任何自定义的类。
使用泛型首先在定义类的地方修改,使其可以存放类型为E的数据。
然后相关的数据类型都需要修改。
一个重要的地方就是在创建data的时候,必须使用强制类型转换,才能创建E类型的data。
public class Array_wide<E> {
private E[] data; // 只能存整形的数组
private int size; // 用于控制数组大小
// 构造函数,传入数组的容量构造Array
public Array_wide(int capacity){
data = (E[])new Object[capacity]; // new一个object类然后强制类型转换为E
size = 0;
}
比如这些地方 需要往数组存放的时候,类型都需要相应修改。
//向所有元素后添加一个元素
public void addLast(E e){
if(size == data.length)
throw new IllegalArgumentException("AddLast failed,Array is full");
data[size] = e;
size ++;
}
泛型修改完成后,还有一种情况,当数组达到capacity上限之后,我们需要对数组扩容,也就是使用动态数组。
动态数组的逻辑是将原data中数据存入新的newData中,newData的容量是data两倍或者更大,再将data指向newData,完成扩容,原data的空间会被释放。
那么需要新增一个resize方法,然后修改add方法和remove方法,当数据量超出或者过小的时候调用resize方法。
public void add(int index, E e){
if(size == data.length)
//throw new IllegalArgumentException("AddLast failed,Array is full");
resize(2*data.length); // 动态数组能力
if(index < 0 || index > size)
throw new IllegalArgumentException("AddLast failed,index illegal");
for (int i = size - 1; i >=index; i --)
data[i+1] = data[i]; // 后移一位
data[index] = e;
size ++;
}
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; // loitering objects != memory leak
if(size == data.length / 4 && data.length / 2 != 0) // 防止复杂度震荡 使用lazy的方法 且防止缩为0
resize(data.length / 2); //动态数组
return ret; // return对应的是remove这个方法
}
动态数组: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;
}