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 位置的元素设为 value
public void set(int pos, int value);
//删除第一次出现的关键字key
public void remove(int toRemove);
// 获取顺序表长度
public int size() ;
// 清空顺序表
public void clear() ;
// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
public void display();
}
MyArrayList的实现
首先需要重写IList接口
后续还会添加方法到接口
public class MyArrayList implements IList{
@Override
public void add(int data) {
}
@Override
public void add(int pos, int data) {
}
@Override
public boolean contains(int toFind) {
return false;
}
@Override
public int indexOf(int toFind) {
return 0;
}
@Override
public int get(int pos) {
return 0;
}
@Override
public void set(int pos, int value) {
}
@Override
public void remove(int toRemove) {
}
@Override
public int size() {
return 0;
}
@Override
public void clear() {
}
@Override
public 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;
}
删除某一个值
先判断一下是否有该数值,如果没有就直接返回
@Override
public 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--;
}
返回元素个数
@Override
public int size() {
return this.usedSize;
}
清空数组
public void clear() {
this.usedSize = 0;
}
ArrayListd底层代码分析
for each遍历list的变量
使用迭代器
ArrayList的优缺点