本文的测试样例是基于上文 数组模拟队列之深度解析 - 掘金 (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)剩余代码较为简单,读者自行理解即可