首先我们可以通过java中的数组作为基础,来进行一系列的改造,创造我们自己的数组类型,例如增删改查,同时为了让我们的数组可以承载任意类型的元素,我们将使用泛型,也同时实现数组的可伸缩,让其更加灵活
public class Array<E> {
private E[] data;
private int Size;
//构造函数,传入数组的容量capacity构造Array
public Array(int capacity) {
data = (E[]) new Object[capacity];
Size = 0;
}
//无参构造器,默认数组的容量capacity=10
public Array() {
this(10);
}
//获取数组中元素的个数
public int getSize() {
return Size;
}
//获取数组的容量
public int getcapacity() {
return data.length;
}
//判断数组是否为空
public boolean isEmpty() {
return Size == 0;
}
//向所有元素最后一位添加新元素
public void addLast(E e) {
add(Size,e);
}
//向所有元素第一位添加一个新元素
public void addFirst(E e) {
add(0,e);
}
//在index位置插入一个新的元素
public void add(int index, E e) {
if(index < 0 || index > Size) {
throw new IllegalArgumentException("add failed.Require index > 0 and index <= Size");
}else {
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 ++;
}
}
//获取index位置的元素
E get(int index) {
if(index < 0 || index >= Size) {
throw new IllegalArgumentException("Get failed.Index is illegal.");
}
return data[index];
}
//获取第一个元素
public E getFirst() {
return get(0);
}
//获取最后一个元素
public E getLast() {
return get(Size - 1);
}
//修改index索引位置的元素
void set(int index, E e) {
if(index < 0 || index >= Size) {
throw new IllegalArgumentException("Get failed.Index is illegal.");
}
data[index] = e;
}
//查找数组中是否有元素e
public boolean contains(E e) {
for(int i = 0; i < Size; i ++) {
if (data[i] == e) {
return true;
}
}
return false;
}
//查找数组中元素e的索引,若是没有,返回-1
public int find(E e) {
for(int i = 0; i < Size; i ++) {
if (data[i].equals(e)) {
return i;
}
}
return -1;
}
//从数组中删除index元素,并返回删除的元素
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;
}
//从数组中删除第一个元素,并返回
public E removeFirst() {
return remove(0);
}
//从数组中删除最后一个元素,并返回
public E removeLast() {
return remove(Size-1);
}
//从数组中删除元素e,(如果没有就啥也不用干)
public void removeElement(E e) {
int index = find(e);
if(index != -1)
remove(index);
}
@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;
}
}
在对这个复杂度的分析中,我们应该取最坏的进行分析,当然最坏的可能发生概率很小,此时我们可以进行均摊复杂度分析,这样更加适合,同时在以上的数组扩容的操作中,我们需要注意一个问题,那就是复杂度的震荡,我们应该选择适当的数组容量伸缩的时机来防止这个问题。