MyArrayList顺序结构:
接口和MyArrayList重写接口
接口
接口中的方法是很多类通用的,所以可以写到接口中
public interface IList {public void add(int data) ;// 在 pos 位置新增元素public void add(int pos, int data);// 判定是否包含某个元素public boolean contains(int toFind) ;// 查找某个元素对应的位置public int indexOf(int toFind) ;// 获取 pos 位置的元素public int get(int pos) ;// 给 pos 位置的元素设为 valuepublic void set(int pos, int value);//删除第一次出现的关键字keypublic void remove(int toRemove);// 获取顺序表长度public int size() ;// 清空顺序表public void clear() ;// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的public void display();}
MyArrayList的实现
首先需要重写IList接口
后续还会添加方法到接口
public class MyArrayList implements IList{@Overridepublic void add(int data) {}@Overridepublic void add(int pos, int data) {}@Overridepublic boolean contains(int toFind) {return false;}@Overridepublic int indexOf(int toFind) {return 0;}@Overridepublic int get(int pos) {return 0;}@Overridepublic void set(int pos, int value) {}@Overridepublic void remove(int toRemove) {}@Overridepublic int size() {return 0;}@Overridepublic void clear() {}@Overridepublic void display() {}
}
基本要素:
顺序接口中,在存储元素的时候,需要有一个数组自己来创建(定义数组 给数组分配内存 数组初始化)需要一个记录数组中元素的个数-计数器
public int[] elem;public int usedSize;public static final int DEFAULT_SIZE = 10;public MyArrayList(){this.elem = new int[DEFAULT_SIZE];}public MyArrayList(int capacity){this.elem = new int[capacity];}
遍历并打印
打印的个数是有计数器决定的
public void display() {for (int i = 0; i < this.usedSize; i++) {System.out.print(elem[i]+" ");}System.out.println();}
add
插入的时候需要检查容量是否满,然后是否扩容
所以可以单独写一个方法来实现检查慢不慢和要不要扩容
private void checkCapacity(){if(isFull()){elem = Arrays.copyOf(elem,elem.length*2);}}
//不是用户要用到的封装起来
尾插数据元素
public void add(int data) {checkCapacity();elem[this.usedSize] = data;this.usedSize++;}
根据下表插入
插入需要检查下标是否异常 所以选哟写一个异常类
在插入的过程中
public void add(int pos, int data) {try {checkPosOnAdd(pos);}catch (PosIllegality e){e.printStackTrace();//异常就不用检查容量了return;}checkCapacity();//1.从最后一个元素往后移 2. 当i到 pos 位置时结束for (int i = this.usedSize - 1; i >= pos ; i--) {elem[i+1] = elem[i];}//插入data元素elem[pos] = data;//usedSize++this.usedSize++;}
检查下标
private void checkPosOnAdd(int pos)throws PosIllegality{if(pos < 0 || pos > this.usedSize){System.out.println("不符合法");throw new PosIllegality("插入元素下标异常" + pos);}}
下标异常类
public class PosIllegality extends RuntimeException{public PosIllegality(String msg){super(msg);}
}
检查是否包含某个元素
首先需要判断数组是不是空
public boolean contains(int toFind) {if(isEmpty()){return false;}for (int i = 0; i < this.usedSize; i++) {if (elem[i] == toFind){return true;}}return false;}
判断是否为满或者空
public boolean isFull(){return this.usedSize == elem.length;}
public boolean isEmpty(){return this.usedSize == 0;}
查找某个元素对应的位置
public int indexOf(int toFind) {if(isEmpty()){return -1;}for (int i = 0; i < this.usedSize; i++) {if (elem[i] == toFind){return i;}}return -1;}
获取pos位置的值
public int get(int pos) {checkPosOnGetAndSet(pos);if(isEmpty()){throw new MyArrayEmpty("获取下标元素" + "顺序表为空");}return elem[pos];}
其中也要检查为空,但返回的时候必须抛异常,以免返回数字认为是该下标的值
Get和Set检查下标合法性
private void checkPosOnGetAndSet(int pos)throws PosIllegality{if(pos < 0 || pos >= this.usedSize){System.out.println("不符合法");throw new PosIllegality("获取元素下标异常" + pos);}}
Set和Get为空时异常类
public class MyArrayEmpty extends RuntimeException{public MyArrayEmpty(String msg){super(msg);}
}
更新pos的值
public void set(int pos, int value) {checkPosOnGetAndSet(pos);elem[pos] = value;}
删除某一个值
先判断一下是否有该数值,如果没有就直接返回
@Overridepublic void remove(int toRemove) {int index = indexOf(toRemove);if(index == -1){System.out.println("没有这个数字");return;}for (int i = toRemove; i < this.usedSize - 1; i++){elem[i] = elem[i+1];}this.usedSize--;}
返回元素个数
@Overridepublic int size() {return this.usedSize;}
清空数组
public void clear() {this.usedSize = 0;}
ArrayListd底层代码分析
for each遍历list的变量
使用迭代器
ArrayList的优缺点