用数组编写一个ArrayList类

时间:2020-12-18 21:58:07

粗略的用数组来实现了ArrayList的方法,不够完善之处继续改正~~
以下是代码:

先定义一个自定义的异常类,用于抛出异常

/**
* 自定义的MyArrayList的异常类,用于提示MyArrayList操作中的各种异常
* @author Z-HaiSome
*/

public class MyArrayList_Exception extends Exception{

public MyArrayList_Exception(){

}

public MyArrayList_Exception(String message){
super(message);
}
}

再定义一个主类:

/**
*用数组写一个类似于ArrayList的类
* @author Z-HaiSome
*/

import java.util.*;

public class MyArrayList{

//定义初始数组长度defaultLength,值为10,有方法可以修改
private int defaultLength = 10;

//定义一个空数组MyList
private Object[] myList = null;

/*
*定义一个数组剩余可用长度,方便添加数据时使用
*如Object数组o长度为5,只有o[3]、[4]没有有效值,则overPlus为2
*/

private int overPlus = 0;

/**
* 创建一个默认长度的空列表
*/

public MyArrayList(){
myList = new Object[defaultLength];
overPlus = defaultLength;
}


/**
* 构造一个包含指定 collection 的元素的对象
* @param c 需要包含的collection接口实现类对象
*/

public MyArrayList(Collection c){
Object[] cTemp = c.toArray();
int lengthTemp = cTemp.length;
myList = Arrays.copyOf(cTemp, lengthTemp+defaultLength);
overPlus = defaultLength;
}

/**
* 构造一个具有指定初始容量的空列表
* 长度小于或等于0时抛出异常
* @param length 指定的初始长度
* @throws MyArrayList_Exception
*/

public MyArrayList(int length) throws MyArrayList_Exception{
if(length<=0){
throw new MyArrayList_Exception("Function error:MyArrayList(int length).0");
}else{
myList = new Object[length];
}
overPlus = length;
}

/**
* 更改默认创建数组长度
* 长度小于1时抛出异常
* @param length 需要更改的目标长度值
* @throws MyArrayList_Exception
*/

public void changeLength(int length) throws MyArrayList_Exception{
if(length<=0){
throw new MyArrayList_Exception("Function error:changeLength(int length).0");
}else{
this.defaultLength = length;
}
}

/**
* 添加元素
* @param addE 需要添加的元素
* @return 是否添加成功,true为添加成功,false为添加失败
* @throws MyArrayList_Exception
*/

public boolean add(Object addE)throws MyArrayList_Exception{
boolean rtn = false;
int length = myList.length;
if(overPlus > 0){
//还有剩余空间时添加元素
myList[length - overPlus] = addE;
overPlus = overPlus-1;
rtn = true;
}else if(overPlus == 0){
//没有剩余空间则创建新数组,长度为原来数组的1.33倍
int addLength = (length/3)>0?(length/3):1; //防止除以3后为0,最小为1
Object[] listTemp = Arrays.copyOf(myList, length+addLength);
myList = listTemp;
listTemp = null;
overPlus = addLength;
//递归回去
add(addE);
}else{
throw new MyArrayList_Exception("Function error:add(Object addE).0");
}
return rtn;
}

/**
* 添加元素到指定位置
* 隔空添加元素将抛出异常
* @param index 需要添加元素的索引位置
* @param addE 需要添加的元素
* @return 是否添加成功,true为添加成功,false为添加失败
* @throws MyArrayList_Exception
*/

public boolean add(int index, Object addE) throws MyArrayList_Exception{
boolean rtn = false;
int length = myList.length;
if(index>length-overPlus){
//隔空添加元素抛出异常
throw new MyArrayList_Exception("不能隔空添加元素!");
}else if(index == length-overPlus){
//恰好在最后一个有效元素后添加
add(addE);
rtn = true;
}else{
//在有效元素中间添加元素
Object[] arrayTemp = new Object[length+1];

//利用arraycopy方法分两次复制数组
System.arraycopy(myList,0, arrayTemp,0, index+1);
System.arraycopy(myList,index+1, arrayTemp,index+2, length-index-1);
arrayTemp[index] = addE;

myList = arrayTemp;
arrayTemp = null;

//剩余空位没有变,overPlus不用更改
rtn = true;
}
return rtn;
}

/**
* 清除所有元素
* @return 是否清除成功,true表示清除成功,false表示清除失败
*/

public boolean clearAll(){
boolean rtn = false;

int length = myList.length;
myList = new Object[length];
overPlus = length;

return true;
}

/**
* 检查是否包含指定元素
* @param o 需要查找的元素
* @return 有则返回第一处的下标,无则返回-1
*/

public int contains(Object o){
int rtn;

//用转为字符串来检查是否有该元素,这样应该比遍历快吧
String temp = Arrays.toString(myList);
if(temp.indexOf(o.toString())==-1){
//如果不存在该元素则返回-1
rtn = -1;
}else{
for(rtn=0; rtn<myList.length-overPlus; rtn++){
if(myList[rtn].equals(o)){ //这里应该用equals,试过==,0.9会出错
break;
}
}
}
return rtn;
}

/**
* 返回列表的有效大小
* @return 列表的有效大小
*/

public int size(){
int vaildLength = myList.length - overPlus;
return vaildLength;
}

/**
* 返回元素数组
* @return 将列表按照数组返回,数组的类型为Object[]
*/

public Object[] toArray(){
int length = myList.length;
Object[] arrayTemp = Arrays.copyOf(myList, length-overPlus);
return arrayTemp;
}

/**
* 按照下标返回元素
* @param index 需要返回元素的索引
* @return 该索引处的元素
* @throws MyArrayList_Exception
*/

public Object get(int index) throws MyArrayList_Exception{
Object rtn = null;
//最大vaildIndex有效的下标
int vaildIndex = myList.length -overPlus -1;


if(index<0){
throw new MyArrayList_Exception("Function error:get(int index):0");
}else if(index>vaildIndex){
throw new MyArrayList_Exception("Function error:get(int index):1");
}else{
rtn = myList[index];
}

return rtn;
}

/**
* 移除元素
* @param index 需要移除的元素索引
* @return 是否移除成功,true表示移除成功,false表示移除失败
* @throws MyArrayList_Exception
*/

public boolean remove(int index) throws MyArrayList_Exception{
boolean rtn = false;
//最大vaildIndex有效的下标
int vaildIndex = myList.length -overPlus -1;

if(index < 0){
throw new MyArrayList_Exception("Function error:remove.0");
}else if(index > vaildIndex){
//超出有效长度
throw new MyArrayList_Exception("Function error:remove.1");
}else{
Object[] arrayTemp = new Object[myList.length -1];
System.arraycopy(myList,0, arrayTemp,0, index);
System.arraycopy(myList,index+1, arrayTemp,index, myList.length-index-1);

myList = arrayTemp;
arrayTemp = null;
}

return rtn;
}

}

测试类用来测试,

import java.util.*;
public class Test{
public static void main(String[] args) throws MyArrayList_Exception{
MyArrayList myl = new MyArrayList();
System.out.println("myl的长度为:"+myl.size());
System.out.println("***************************");


myl.add("text1");
myl.add(111);
myl.add(0.9);
myl.add("text2");
myl.add("text3");
myl.add(222);
myl.add(4444);
myl.add(666);
System.out.println("添加8个元素后,myl的长度为:"+myl.size());
System.out.println("***************************");


myl.add("元素9");
myl.add("元素10");
myl.add("元素11");
System.out.println("添加多3个元素后,看看超出默认长度可不可以,myl的长度为:"+myl.size());
for(int i=0;i<myl.size();i++){
System.out.println("myl["+i+"]="+myl.get(i));
}
System.out.println("***************************");


myl.remove(1);
myl.remove(6);
myl.remove(2);
System.out.println("删除下标为1.6.2三个元素后,myl的长度为:"+myl.size());
for(int i=0;i<myl.size();i++){
System.out.println("myl["+i+"]="+myl.get(i));
}
System.out.println("***************************");


Object temp = myl.get(0);
System.out.println("获得myl[0]:"+temp);
System.out.println("***************************");


int co;
co = myl.contains(2222);
System.out.println("不存在2222,返回-1: "+co);
co = myl.contains("text1");
System.out.println("存在text1,返回下标0: "+co);
co = myl.contains(0.9);
System.out.println("存在0.9,返回下标1: "+co);
System.out.println("***************************");

myl.clearAll();
System.out.println("清除所有元素后,列表长度为:"+myl.size());
System.out.println("***************************");
}
}

得到结果:
用数组编写一个ArrayList类

测试的时候这几个类应该放到同一个文件夹里面~