基础版可参考文章:快递e栈(控制台简易版)——最最最基础
集合存储版可参考文章:快递e栈(控制台简易版)——集合
IO流文件存储版可参考文章: 快递e栈(控制台简易版)——IO流
快递e栈(控制台简易版)——异常处理
考察内容:二维数组 + 面向对象 + 异常处理
本节任务用于熟悉快递管理业务,完成快递管理控制台项目,具体需求如图。
任务过程
1. 明确需求,使用面向对象的思想创建快递类,包含快递位置,单号,公司,取件码等
2. 使用二维数组保存快递信息,建议数组第一个位置为柜子位置,第二个位置为快递对象
3. 根据任务需求,定义相关方法(新增快递,删除快递,修改快递,查看所有快递)
4. 创建用户类,定义角色属性,用以区分管理员和普通用户
5. 测试:使用不同用户角色切换,按照任务概述实现功能测试和验收
对于上一版本最基础版我们采用了面向对象的思想创建了多个类,每个类都有每个类单独的作用,根据任务需求在相关的类定义了相关的的方法,简单提高了项目的业务逻辑。但是本项目使用二维数组保存快递信息,最多只能存入三个快递,如果想增加的话可自行将二维数组的行数进行修改,对循环的循环次数进行修改。
自我认为本项目对于异常处理的判断和业务逻辑处理还有待改进,try/catch的理解还不是很到位,大佬们有见解的话希望可以指正。
代码实现如下
Express类
//将同一个包下的其余类中的静态方法导入到此类中,这两行代码需要自行导包,不能直接复制
import static mission.demo02.Courier.deliveryman;
import static mission.demo02.User.user;
import java.util.Scanner;
//快递类
public class Express {
//二维数组存储快递信息,第二维下标分别为:0-快递单号 1-快递公司名称 2-取件码
static String[][] parcelInfo = new String[3][3];
public static void start(){
//获取输入数据
Scanner sc = new Scanner(System.in);
String inputString;
int input = -1;
//进入系统
system:while (true){
System.out.println("=====欢迎使用快递e栈快递柜=====");
System.out.println("请输入您身份:1-快递员 2-用户 退出系统请输入exit");
inputString = sc.next();
//根据打开相应界面或退出系统
if(inputString.equals("1")){
//进入快递员界面,传入输入数据,传入快递信息数组
deliveryman(sc,parcelInfo);
}else if(inputString.equals("2")){
//进入用户界面,传入输入数据
user(sc,parcelInfo);
}else if(inputString.equals("exit")){
//退出系统
break system;
}else {
try{
input = Integer.parseInt(inputString);
if (input < 1 || input > 2){
System.out.println("请输入正确的数字!");
}
}catch (NumberFormatException e){
System.out.println("请输入正确的数字!");
}
}
}
System.out.println("=====系统已退出,感谢您的使用=====");
}
//快递员相关操作
//存库快递方法
public static void saveParcel(Scanner sc, String[][] parcelInfo) {
saveParcel:while (true) {
//遍历数组寻找空闲格子
for (int i = 0; i < 3; i++) {
//判断当前格子是否为空
if (parcelInfo[i][0] == null) {
System.out.println("请输入快递单号");
String inputString = sc.next();
//存入快递单号
parcelInfo[i][0] = inputString;
System.out.println("请输入公司名称");
inputString = sc.next();
//存入公司名称
parcelInfo[i][1] = inputString;
//计算随机取件码存入快递信息
int getRadom = (int)((Math.random() * 9 + 1) * 100000);
System.out.println("快递已存入,取件码为:" + getRadom);
parcelInfo[i][2] = getRadom + "";//随机数转化为字符串
//结束存快递操作
break saveParcel;
}
if (parcelInfo[2][0] != null) {
try{
if (parcelInfo[i][0] != null){
System.out.println("存不下啦!");
break saveParcel;
}
}catch (IndexOutOfBoundsException e){
System.out.println("存不下啦!");
break saveParcel;
}
}
}
break saveParcel;
}
}
//删除快递方法
public static void deleteParcel(Scanner sc,String[][] parcelInfo){
deleteParcel:while (true) {
//输入单号,查找数组中的单号
System.out.println("请输入要删除的快递单号");
String inputString = sc.next();
for (int i = 0; i < 3; i++) {
//找到对应单号
if (inputString.equals(parcelInfo[i][0])) {
//删除快递单号
parcelInfo[i][0] = null;
parcelInfo[i][1] = null;
parcelInfo[i][2] = null;
System.out.println("单号:" + inputString + " 删除成功");
break deleteParcel;
}
if (!inputString.equals(parcelInfo[i][0])) {
try{
System.out.println("未找到单号为" + inputString + "的快递");
break deleteParcel;
}catch (Exception e){
System.out.println("未找到单号为" + inputString + "的快递");
break deleteParcel;
}
}
}
break deleteParcel;
}
}
//修改快递信息方法
public static void amendParcelInfo(Scanner sc,String[][] parcelInfo){
amendParcelInfo:while (true) {
//输入单号,查找数组中的单号
System.out.println("请输入要修改的快递单号");
String inputString = sc.next();
for (int i = 0; i < 3; i++) {
//找到对应单号
if (inputString.equals(parcelInfo[i][0])) {
//修改快递单号
System.out.println("请输入新的快递单号");
inputString = sc.next();
//存入快递单号
parcelInfo[i][0] = inputString;
System.out.println("请输入公司名称");
inputString = sc.next();
//存入公司名称
parcelInfo[i][1] = inputString;
System.out.println("修改成功!");
break amendParcelInfo;
}
if (!inputString.equals(parcelInfo[i][0])) {
try{
System.out.println("未找到单号为" + inputString + "的快递");
break amendParcelInfo;
}catch (Exception e){
System.out.println("未找到单号为" + inputString + "的快递");
break amendParcelInfo;
}
}
}
break amendParcelInfo;
}
}
//查看所有快递方法
public static void checkAllParcel(String[][] parcelInfo){
if (parcelInfo[0][0] == null) {
try{
System.out.println("快递柜暂无快递!");
}catch (Exception e){
System.out.println("快递柜暂无快递!");
}
} else {
System.out.println("所有快递信息如下:");
System.out.println("快递单号"+ "\t" + "公司名称"+ "\t" + "取件码");
checkAllParcel:while (true) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (parcelInfo[i][j] != null) {
System.out.print(parcelInfo[i][j] + "\t");
}
}
if (parcelInfo[i][0] != null) {
//打印完一条信息换行
System.out.println("");
}
}
break checkAllParcel;
}
}
}
}
Courier类
//将同一个包下的其余类中的静态方法导入到此类中,这行代码需要自行导包,不能直接复制
import static mission.demo02.Express.*;
import java.util.Scanner;
//快递员类
public class Courier {
//快递员界面
public static void deliveryman(Scanner sc, String[][] parcelInfo){
int input = -1;
deliverymanInterface:while (true) {
System.out.println("当前身份为 快递员 请选择操作:1-存快递 2-删除快递 3-修改快递信息 4-查看所有快递 返回上一级请输入exit");
String inputString = sc.next();
if (inputString.equals("1")) {
//调用存快递方法,传入输入数据,传入快递信息数组
saveParcel(sc,parcelInfo);
} else if (inputString.equals("2")) {
//调用删除快递方法,传入输入数据,传入快递信息数组
deleteParcel(sc,parcelInfo);
} else if (inputString.equals("3")) {
//调用修改快递信息方法,传入输入数据,传入快递信息数组
amendParcelInfo(sc,parcelInfo);
}else if (inputString.equals("4")) {
//调用查看所有快递方法,传入输入数据,传入快递信息数组
checkAllParcel(parcelInfo);
}else if (inputString.equals("exit")) {
//退出快递员界面
break deliverymanInterface;
}else {
try{
input = Integer.parseInt(inputString);
if (input < 1 || input > 4){
System.out.println("请输入正确的数字!");
}
}catch (NumberFormatException e){
System.out.println("请输入正确的数字!");
}
}
}
}
}
User类
import java.util.Scanner;
//用户类
public class User {
//用户界面
public static void user(Scanner sc, String[][] parcelInfo){
userInterface:while (true) {
System.out.println("当前身份为 用户 请输入取件码: 返回上一级请输入exit");
String inputString = sc.next();
if (inputString.equals("exit")) {
break userInterface;
}else{
//调用取快递方法,传入输入数据,传入快递信息数组
getParcel(inputString,parcelInfo);
}
}
}
//用户相关操作
//取件方法
public static void getParcel(String inputString,String[][] parcelInfo){
getParcel:while (true) {
//输入单号,查找数组中的单号
for (int i = 0; i < 3; i++) {
//找到对应单号
if (inputString.equals(parcelInfo[i][2])) {
//删除快递单号
parcelInfo[i][0] = null;
parcelInfo[i][1] = null;
parcelInfo[i][2] = null;
System.out.println("取件成功!");
break getParcel;
}
}
for (int i = 0; i < 3; i++) {
if (!inputString.equals(parcelInfo[i][2])) {
try {
System.out.println("未找到取件码为" + inputString + "的快递");
break getParcel;
} catch (Exception e) {
System.out.println("未找到取件码为" + inputString + "的快递");
break getParcel;
}
}
}
break getParcel;
}
}
}
Test类
public class Test {
public static void main(String[] args) {
Express e = new Express();
e.start();
}
}
小贴士:
循环标签的使用
//项目整体利用了循环标签,在循环外部做一个标记,格式为:
xxx:for(){
//循环内容
break xxx;//break到标签的位置
}
//如果在只有一重的循环设置标签,其实是无意义的,因为 break + 标签 就是跳出了循环
//标签一般在多重循环较为好用,例如:
outer:for(int i = 0; i < 10; i++){
inner:for (int j = 0; j < 10; j++) {
if(i == 5){
System.out.println("outer");
break outer;//break到i层的循环
}
if (j == 5){
System.out.println("inner");
break inner;//break到j层的循环
}
}
}
但是本文中使用循环标签时只是在一重循环里使用,并未真正体现循环标签的作用,将标签删除对程序也是没有任何影响的。