目录
ArrayList是List接口的一个实现类,它是程序中最常见的一种集合。在ArrayList内部封装一个长度可以改变的数组对象,当存入的元素超过数组长度,ArrayList会在内存中分配一个更大的数组来存储这些元素,因此可以将ArrayList集合看作一个长度可变的数组,在使用ArrayList之前,实现一个MyArrayList来对数组进行简单的操作。
一、定义接口
首先定义一个接口,对要实现的操作进行简单的列举。
public interface IList { //打印数组 public void dispiay(); //插入数组 public void OnAdd(int data); //在pos位置放入元素 public void FixOnAdd(int pos,int val); //查找某个元素对应的位置 public int Found(int toFind); //获取某个下标对应的元素 public int Get(int pos); //判断是否包含某个元素 public boolean contains(int toFind); //更新元素 public void set(int pos,int val); //获取顺序表长度 public int size(); //删除元素 public void remove(int toRemove); //清空元素 public void clear(); }
二、定义方法
定义一个MyArrayList类来实现这个接口,对接口中的方法进行具体的实现。
MyArrayList本质是一个数组:
public class MyArrayList implements IList { int usedSize; //数组里元素的个数 public int[]elem; //定义成一个数组 public static final int defSize=10; //默认数组大小 public MyArrayList(){ this.elem=new int[defSize]; } public MyArrayList(int capacity){ //自定义数组大小 this.elem=new int[capacity]; }
1、遍历元素
MyArrayList本质是一个数组,所以可以遍历数组中的元素来打印。
public void dispiay() { for (int i = 0; i <this.usedSize; i++) { System.out.print(elem[i]+" "); } System.out.println(); }
2、放入元素
在数组中放入元素默认是放在数组的最后一位,要判断数组是否满了,满了就无法放入。
判断数组是否满了:
public boolean isFull() { if (usedSize == elem.length) { return true; } return false; }
满了需要对数组进行扩容:
private void CheckFULL(){ if (isFull()){ //满了进行扩容,通过对原来数组进行拷贝,放到扩容的数组中 elem= Arrays.copyOf(elem,elem.length*2); } }
将判断数组是否已经满了,满了进行扩容整体封装成一个对象,对后续同样的操作进行直接使用。
判断完成之后就可以进行放入元素:
public void OnAdd(int data) { CheckFULL(); //放最后一位,usedSize的位置 this.elem[this.usedSize]=data; this.usedSize++; }
3、插入元素
在指定的位置进行插入元素,使用pos来记录要插入的位置下标。对pos要检查合法性,要按顺序存放,不能小于0下标,不能大于按顺序要放入的下标。如果pos位置不合法要抛出一个异常,来对pos进行处理。
先定义一个异常:
public class CheckPosException extends RuntimeException{ public CheckPosException(String msg){ super(msg); } }
检查pos的合法性:
private void Checkpos(int pos)throws CheckPosException{ if (pos<0 ||pos>this.usedSize){ throw new CheckPosException("pos输入异常"+pos); } }
因为后续也要对pos进行检查,使用封装成一个对象。
插入元素:
public void FixOnAdd(int pos, int data) { try { Checkpos(pos); } catch (CheckPosException e) { e.printStackTrace(); return; } CheckFULL();//检查是否需要扩容 for (int i = usedSize-1; i >=pos; i--) { //从usedSize-1开始 elem[i + 1] = elem[i]; //插入元素,将插入元素后面位置的元素进行往后移 } elem[pos] = data; usedSize++; }
4、包含元素
查找是否包含某个元素
先判断数组是否为空:
public boolean isEmpty(){ return usedSize==0;
}
不为空就可以通过遍历数组来找对应的元素:
public boolean contains(int toFind) { if (isEmpty()) { return false; } for (int i = 0; i < usedSize; i++) { if (elem[i]==toFind){ return true; } } return false; } public boolean isEmpty(){ return usedSize==0; }
5、查找下标
查找对应元素的下标,通过对数组的遍历可以查找到对应元素的下标。
public int Found(int toFind) { if (isEmpty()) { return -1; } for (int i = 0; i < usedSize; i++) { if (elem[i]==toFind){ return i; } } return -1; }
6、查找元素
获取某个下标对应的元素:
用pos来表示下标,需要对pos进行检查,pos不能小于0,也不能大于等于usedSize,当等于usedSize,没有元素。
先检查pos:
private void CheckposGetAndSet(int pos)throws CheckPosException{ if (pos<0 ||pos>=this.usedSize){ throw new CheckPosException("pos输入异常"+pos); } }
数组为空也不可以获取下标对应的元素,当数组为空时,定义一个异常:
public class MyArrayListEmpty extends RuntimeException{ public MyArrayListEmpty(String msg){ super(msg); } }
查找元素:
public int Get(int pos) throws MyArrayListEmpty{ CheckposGetAndSet(pos); if (isEmpty()){ throw new MyArrayListEmpty("获取指定下标对应的元素时,顺序表为空"); } return elem[pos]; }
7、更新元素
将pos位置对应的元素改成val,传入一个pos和一个要改为的val。
先检查pos的合法性:
CheckposGetAndSet(pos);
更新元素:
public void set(int pos,int val) { CheckposGetAndSet(pos); elem[pos]=val; }
8、获取长度
获取顺序表长度就是当前的usedSize:
public int size() { return this.usedSize; }
9、删除元素
删除元素就是将要删除的元素下标记录下来,将这个元素下标的后一位往前进行覆盖。
public void remove(int toRemove) { int index=Found(toRemove);//记录下标 if (index==-1){ System.out.println("没有这个数字"); return; } for (int i=index;i<usedSize-1;i++){//往前覆盖,原来最后一位的元素就到了前一位,所以要-1 elem[i]=elem[i+1]; } usedSize--;//删除-1 }
10、清空元素
对应存放基本数据类型的数组,直接将usedSize置为0,就可以清空数组。
public void clear() { this.usedSize=0; } }
三、使用方法
重新定义一个类,定义一个mian方法就调用定义的方法。
打印数组元素都用:
myArrayList.dispiay();
public class Main {
public static void main(String[] args) {
MyArrayList myArrayList=new MyArrayList();//实例化数组
System.out.println("***放入元素***");
myArrayList.OnAdd(1);
myArrayList.OnAdd(2);
myArrayList.OnAdd(3);
myArrayList.dispiay();
System.out.println("***插入元素***");
myArrayList.FixOnAdd(1,3);
myArrayList.dispiay();
System.out.println("***判断是否包含元素***");
System.out.println( myArrayList.contains(1));
System.out.println("***查找元素对应下标***");
int a=myArrayList.Found(2);
System.out.println(a);
System.out.println("***查找下标对应的元素***");
int b=myArrayList.Get(2);
System.out.println(b);
System.out.println("***更新元素***");
myArrayList.set(1,1);
myArrayList.dispiay();
System.out.println("***数组长度大小***");
System.out.println(myArrayList.size());
System.out.println("***删除元素***");
myArrayList.remove(1);
myArrayList.dispiay();
System.out.println("***清空元素***");
myArrayList.clear();
myArrayList.dispiay();
}
}
执行结果: