用数组模拟ArrayList,首先需要要创建一个类,然后在类中声明一个数组,(面向对象要求再创建对象的时候再进行初始化,所以留到构造方法中再进行数组的初始化)包含数组的属性,还有操作数组的一些方法,包括最基本的增加(add),删除(remove),修改(set),和查询(get)方法,在添加元素是若空间不足,应考虑扩容(inchCapacity),ArrayList自动扩容机制扩容1.5倍,此处也模拟扩容1.5倍。最后输出时默认调用的toString方法,输出的是对象,因此需要重写toString方法来实现数组的输出。
(一)指定类型模拟
public class MyList {
//声明一个数组
private String[] array =null;
//表示数组长度
private int size;
// 表示数组索引
int index =-1;
//构造方法初始化数组长度
public MyList(int size) {
this.size = size;
array =new String [size];
}
//添加元素
public void add(String value) {
//判断 空间是否已满
if(index==size-1){
index++;
array=incCapacity(array);
array[index]=value;
}else{
array[++index]=value;
}
}
//根据下标获取数组元素
public String get(int index){
if(index>size-1||index<0){
throw new RuntimeException("下标越界");
}
return array[index];
}
//删除数组元素,JDK1.7ArrayList底层删除方式
public void remove(int index){
//从被删除元素的后一位开始,将所有元素截取并拷贝到原数组中,即可实现数组元素的删除
System.arraycopy(array,index+1,array,index,size-index-1);//size-index-1表示被删除元素的后面还剩下几个元素
//完成移动后将最后一个元素设为null
array[size-1]=null;
}
//设置数组元素
public String set(int index,String e){
array[index]=e;
return e;
}
//数组扩容:添加元素时若空间已满,创建一个长度为原数组1.5倍长度的数组,再将原数组赋值到新的数组
public String[] incCapacity(String[] a){
//创建一个长度为原数组长度1.5倍的新数组,并将原来的数组拷贝到扩容后的新数组中
size=size+(size>>1);
String[] newarray= Arrays.copyOf(a,size);
System.out.println("实现扩容1.5倍"+Arrays.toString(newarray));
return newarray;
}
@Override
//重写toString方法,以字符串形式返回数组中的元素
public String toString(){
return Arrays.toString(array);
}
public static void main(String[] args) {
//创建MyList对象,并初始化空间大小为5
MyList list = new MyList(5);
//添加元素
list.add("100");
list.add("120");
list.add("200");
list.add("320");
list.add("500");
list.add("300");
System.out.println(list);//默认调用toString()方法,输出的是地址,要输出数值需要重写toString方法
MyList list2 = new MyList(5);
list2.add("Hello");
list2.add("World");
//获取元素
System.out.println(list2.get(1));//world
System.out.println(list2.get(3));//null
// System.out.println(list2.get(5));//越界异常
//删除元素
list.remove(1);
System.out.println(list);
//设置元素
list.set(0,"500");
System.out.println(list);
}
}
(二)使用泛型模拟
使用泛型需要注意,这里要用Object类型来接收数组(涉及泛型的类型擦除)。返回时也要强制转换成泛型类型。
public class MyList2 <E> {//E表示泛型,
//声明一个数组
private Object[] array =null; //Object类型的数组可以接受任意类型数据
//表示数组长度
private int size;
// 表示数组索引
int index =-1;
//构造方法初始化数组长度
public MyList2(int size) {
this.size = size;
array =new Object[size] ;
}
//添加元素
public void add(E value) {
//判断 空间是否已满
if(index==size-1){
index++;
array=incCapacity(array);
array[index]=value;
}else{
array[++index]=value;
}
}
//根据下标获取数组元素
public E get(int index){
if(index>size-1||index<0){
throw new RuntimeException("下标越界");
}
return (E) array[index];//数组中存储的是Object类型,需要强转为泛型类型后返回
}
//删除数组元素,JDK1.7ArrayList底层删除方式
public void remove(int index){
//从被删除元素的后一位开始,将所有元素截取并拷贝到原数组中,即可实现数组元素的删除
System.arraycopy(array,index+1,array,index,size-index-1);//size-index-1表示被删除元素的后面还剩下几个元素
//完成移动后将最后一个元素设为null
array[size-1]=null;
}
//设置数组元素
public E set(int index,E e){
array[index]=e;
return e;
}
//数组扩容:添加元素时若空间已满,创建一个长度为原数组1.5倍长度的数组,再将原数组赋值到新的数组
public Object[] incCapacity(Object[] a) {
//创建一个长度为原数组长度1.5倍的新数组,并将原来的数组拷贝到扩容后的新数组中
size = size + (size >> 1);
Object[] newarray = Arrays.copyOf(a, size);
System.out.println("实现扩容1.5倍" + Arrays.toString(newarray));
return newarray;
}
@Override
//重写toString方法,以字符串形式返回数组中的元素
public String toString(){
return Arrays.toString(array);
}
public static void main(String[] args) {
MyList2<String> list2 =new MyList2<>(3);
list2.add("100");
list2.add("200");
list2.add("300");
list2.add("300");
list2.add("300");
System.out.println(list2);//[100,200,300]
System.out.println(list2.get(2));//300
}
}