携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
本文的测试样例是基于上文 数组模拟队列之深度解析 - 掘金 (juejin.cn)所进行的测试样例代码深入剖析及源码解读,读者可自行观看上文,再看本文效果最佳
public class demo2 {
public static void main(String[] args) {
ArrayQueue queue = new ArrayQueue(3);
char key = ' ';
Scanner scanner = new Scanner(System.in);
boolean loop = true;
while (loop) {
System.out.println("s(show):显示队列");
System.out.println("e(exit):退出程序");
System.out.println("a(add):添加数据到队列");
System.out.println("g(get):从队列取出数据");
System.out.println("h(head):查看队列头的数据");
key = scanner.next().charAt(0);
上方代码详解
(1)首先创建ArrayQyeye这一对象,并传参数maxSize的值为3
(2)定义一个key变量用于接收用户输入的字符串,使用Scanner类来进行控制台输入与输出,定义一个loop变量用于后续while循环判断true和false
(3)使用loop进行while循环,初始化选项界面
(4)使用key变量接收用户传入的变量并转为字符串进行处理
switch (key) {
case 's':
queue.showQueue();
break;
case 'a':
System.out.println("输出一个数");
int value = scanner.nextInt();
queue.addQueue(value);
break;
case 'g':
try {
int res = queue.getQueue();
System.out.printf("取出的数据是%d\n", res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
int res = queue.headQueue();
System.out.printf("队列头的数据是%d\n", res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'e':
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("程序退出~");
}
}
上方代码详解
(1)使用switch循环匹配用户所输入的字符串,并对每一个case进行break处理
(2)在case:'s'这一分支中,利用ArrayQueue创建出的queue对象调用showQueue()方法,实现对当前队列的展示
(3)在case:'a'这一分支中,先运用 System.out.printf提示用户下一步动作,然后用value变量接受用户传进来的值,利用ArrayQueue创建出的queue对象调用addQueue()方法。(下方为addQueue方法)在addQueue()这一方法中我们可以看到,我们传入了一个n变量用于用户添加数据,此时用户输入的value的值就相当于n变量传入的值
public void addQueue(int n) {
if (isFull()) {
System.out.println("队列已满,不能继续添加数据");
return;
}
rear++;
arr[rear] = n;
}
(4)在case'g'这一分支中,定义一个res用于存储用户想要取出数据的值,并使用queue调用getQueue()方法,最终通过System.out.printf打印输出用户想取出的数据。如果队列为空,则抛出异常并用System.out.printf并调用e.getMessage()方法,此处是很多人疑惑的一个点
我的class里面没有getMessage()这一方法,为什么要调用它呢???
我们点开getMessage()这一方法可以看到(如下图),在源码中作者定义了一个String类型的getMessage()方法,并返回了一个名为detailMessage的一个变量,我们点进detailMessage会发现这是一个private权限、String类型的一个变量(排版问题,故不展示,掘友们可以自行到idea里面去查看)。言归正传,在下图的文档注释中我们可以注意到:“该方法返回的值是String类型的throwable,下面一句话的括号里面补充了这一String类型可能为空的情况”,由此一来,我们可以得出为什么要调用e.getMessage()方法!
(5)在case'h'这一分支中,我们定义一个res变量便于用户查看队列头数据,利用queue去调用headQueue(),最终System.out.printf,同时捕获异常,利用try处理并调用e.getMessage(),理由见(4)
(6)在case'e'这一分支中,我们利用scanner类去调用close(),此时相信很多人的疑惑又来了
我没有写close()啊,这个方法哪来的?!!
我们点开close()这一方法(如下图),可以看到这是一个void类型的方法,在这个方法中,我们利用if函数进行判断:
① 如果为close,立刻return;
② 如果不是,则利用score去调用Closeable接口。此处的score是一个private类型的,readable的一个变量,Closeable接口是关于I/O流的一个异常处理,Closeable本身还继承AutoCloseable接口,AutoCloseable接口本身是用来解决资源不能正常关闭的情况(读者自行去idea验证即可,本文不作赘述) ,由此一来,我们可以得知为什么要调用close()这一方法,其根本原因是为了解决资源不能正常关闭的情况。
(7)剩余代码较为简单,读者自行理解即可
本次数组模拟队列的全文至此全部结束,读者若是有疑惑或作者笔误的情况,欢迎评论区留言,一定认真回复!