Java采用二维数组的方式存储快递;模拟快递柜取件;快递管理系统

  1. 问题描述
    在这里插入图片描述
  2. 解决思路
        该问题模拟日常生活中快递柜取件问题。在程序中,有管理员和用户两个不同身份人员,能进行的操作也不同,为此可以使用switch-case语句进行判断然后进入不同的界面。而在管理员操作功能也有多个,可以再次使用switch-case语句,进行嵌套使用实现。不过为了更好的理解程序,在观看代码时思路不会混乱,可以将第二个switch-case语句包装成新的方法,在第一个语句中调用方法即可实现。
        在程序的设计中采用MVC框架(模型-视图-控制器),V-放置页面显示的所有内容,包括欢迎页面、退出页面、身份选择页面、功能选择页面等等;M-放置与数据库操作有关的方法,即增删改查方法,各个方法之间没有鲁逻辑连接,逻辑连接通过控制器实现;最后通过C-调用M和V中的各个方法,实现各个页面的显示和功能。
        使用MVC框架的好处:减少耦合性。各个页面的显示互不相关,增删改查的实现过程互不相关。在进行后期代码的修改,功能的添加删除等改动代码量大大减少。在进行代码的阅读时也能容易理解,每个功能模块可以单独理解,最后通过控制器的逻辑连接进行理解即可。
  3. 程序代码
    视图展示Views.java
package com.vanessa.express;

import java.util.Scanner;

public class Views {
    Scanner input = new Scanner(System.in);

    /**
     * 欢迎页面
     */
    public void welcome(){
        System.out.println("欢迎使用胡萝卜小区快递管理系统!");
    }
    /**
     * 退出页面
     */
    public void byebye(){
        System.out.println("欢迎下次使用!");
    }
    /**
     * 身份选择页面
     * @return 0.退出 1.管理员 2.用户
     */
    public int menu(){
        System.out.println("请选择您的身份:0.退出 1.管理员 2.用户");
        String text = input.nextLine();
        int num = -1;
        try{
            num = Integer.parseInt(text);
        } catch (NumberFormatException e){ }
        if(0>num || 2<num){
            System.out.println("输入有误,请重新输入!");
            menu();
        }
        return num;
    }

    /**
     * 管理员功能选择页面
     * @return 0.退出  1.快递录入  2.删除快递  3.修改快递  4.查看所有快递
     */
    public int aMenu(){
        System.out.println("请选择您要执行的操作:0.返回上级目录  1.录入快递  2.删除快递  3.修改快递  4.查看所有快递");
        String text = input.nextLine();
        int num = -1;
        try{
            num = Integer.parseInt(text);
        } catch (NumberFormatException e){ }
        if(0>num || 4<num){
            System.out.println("输入有误,请重新输入!");
            aMenu();
        }
        return num;
    }

    /**
     * 用户取快递页面
     */
    public int uMenu(){
        System.out.print("请输入您的取件码进行取件:");
        String text = input.nextLine();
        int num = -1;
        try{
            num = Integer.parseInt(text);
        } catch (NumberFormatException e){ }
        if(100000>num || 9999999<num){
            System.out.println("输入有误,请重新输入!");
            uMenu();
        }
        return num;
    }
    /**
     * 录入快递页面
     * @return e
     */
    public Express insert(){
        System.out.print("请输入快递单号:");
        String code = input.nextLine();
        System.out.print("请输入快递公司:");
        String company = input.nextLine();
        Express e = new Express();
        e.setCode(code);
        e.setCompany(company);
        return e;
    }

    /**
     * 获取快递单号
     * @return 快递单号
     */
    public String findByCode(){
        System.out.print("请输入要操作的快递单号:");
        String code = input.nextLine();
        return code;
    }

    /**
     * 询问是否确认删除页面
     * @return 0.退出 1.确认删除 2.取消操作
     */
    public int delete(){
        System.out.println("是否确认删除? 0.退出 1.确认删除 2.取消操作");
        String text = input.nextLine();
        int num = -1;
        try{
            num = Integer.parseInt(text);
        } catch (NumberFormatException e){ }
        if(0>num || 2<num){
            System.out.println("输入有误,请重新输入!");
            delete();
        }
        return num;
    }

    /**
     * 修改快递单号页面
     * @return 修改后的快递
     */
    public Express update(Express e){
        System.out.print("请输入新的快递单号:");
        String newCode = input.nextLine();
        System.out.print("请输入新的快递公司:");
        String company = input.nextLine();
        e.setCode(newCode);
        e.setCompany(company);
        return e;
    }

    /**
     * 打印快递信息
     * @param e
     */
    public void printExpress(Express e) {
        if (e != null) {
            System.out.println("快递信息如下,快递公司:" + e.getCompany() + ",快递单号:" + e.getCode() + ",取件码:" + e.getNumber());
        }
    }

    /**
     * 打印所有快递信息
     * @param es
     */
    public void printAll(Express[][] es){
        if (es==null || es.length==0){
            System.out.println("快递系统中暂无快递");
            return;
        }
        for(int i=0;i<10;i++){
            for(int j=0;j<10;j++){
                if (es[i][j] != null) {
                    System.out.print("第" + (i + 1) + "排" + (j + 1) + "列");
                    printExpress(es[i][j]);
                }
                //printExpress(es[i][j]);
            }
        }
    }
    /**
     * 删除快递成功页面
     */
    public void deleteSuccess(){
        System.out.println("已经成功删除快递!");
    }
    /**
     * 取件成功页面
     */
    public void successPickup(){
        System.out.println("成功取件!");
    }
    /**
     * 重复存储快递页面
     */
    public void expressExist(){
        System.out.println("此单号快递在快递柜中已经存在,请勿重复存储!");
    }

    /**
     * 对应单号快递不存在页面
     */
    public void expressNotExist(){
        System.out.println("快递柜不存在此单号快递,请重新输入!");
    }
}

数据存取
    Express.java表示快递,其中包含有关快递的相关属性:快递单号、快递公司和取件码已经相关get()、set()、toString()等方法。

package com.vanessa.express;

import java.util.Objects;

public class Express {
    private String company; //快递公司
    private String code;    //快递单号
    private int number;     //取件码

    @Override
    public String toString() {
        return "Express{" +
                "company='" + company + '\'' +
                ", code=" + code +
                ", number=" + number +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Express)) return false;
        Express express = (Express) o;
        return Objects.equals(code, express.code);
    }

    @Override
    public int hashCode() {
        return Objects.hash(code);
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}

    ExpressDao.java包含与数据库的操作方法,即增删改查(各个方法之间任何的逻辑,都是独立的)。

package com.vanessa.express;

import java.util.Random;

public class ExpressDao {
    private Express[][] data = new Express[10][];
    private int size; //当前存储的快递数
    private Random random = new Random();
    {
        for (int i=0;i<10;i++){
            data[i] = new Express[10];
        }
    }
    /**
     * 存取快递
     * @param e
     * @return 存快递成功则返回true,没有位置则返回false
     */
    public boolean add(Express e){
        if (size == 100){
            return false;
        }
        int x = -1;
        int y = -1; //随机生成快递所在行和列
        while (true){
            x = random.nextInt(10);
            y = random.nextInt(10);
            if (data[x][y] == null){//此位置无快递
                break;
            }
        }
        int number = randomNumber();
        e.setNumber(number); //设置快递的取件码
        data[x][y] = e;
        size++;
        return true;
    }

    /**
     * 随机生成取件码
     * @return 快递系统中不存在的取件码
     */
    public int randomNumber(){
        /*int number = random.nextInt(900000)+100000;
        Express e = findByNumber(number);
        if(e != null){
            randomCode();//取件码已经存在,重新分配取件码
        }
        return number;*/
        while (true){
            int number = random.nextInt(900000)+100000;
            Express e = findByNumber(number);
            if(e == null){
                return number;//取件码不重复,可以直接使用
            }
        }
    }

    /**
     * 根据取件码查询快递
     * @param number 取件码
     * @return查询结果,查找到则返回快递信息,否则返回null
     */
    public Express findByNumber(int number){
        for (int i=0;i<10;i++){
            for (int j=0;j<10;j++){
                if(data[i][j] != null) {
                    if (data[i][j].getNumber() == number) {
                        return data[i][j];
                    }
                }
            }
        }
        return null;
    }

    /**
     * 根据单号查询快递
     * @param code 单号
     * @return查询结果,查找到则返回快递信息,否则返回null
     */
    public Express findByCode(String code){
        Express e = new Express();
        e.setCode(code);
        for (int i=0;i<10;i++){
            for (int j=0;j<10;j++){
                if (e.equals(data[i][j])){
                    return data[i][j];
                }
            }
        }
        return null;
    }

    /**
     * 删除快递
     * @param e 需要删除的快递
     */
    public void delete(Express e){
        d:for (int i=0;i<10;i++){
            for (int j=0;j<10;j++){
                if (e.equals(data[i][j])){
                    data[i][j] =null;
                    size--;
                    break d;
                }
            }
        }
    }

    /**
     * 修改快递单号,思路:将要修改的快递删除,再将单号修改后重新添加
     * @param oldE
     * @param newE
     */
    public void update(Express oldE,Express newE){
        delete(oldE);
        add(newE);
    }

    /**
     * 查询所有快递信息
     * @return 将每一个快递信息
     */
    public Express[][] all(){
        return data;
    }
}

调度数据Main.java
    用于将V和M联系起来的内容。通过用户的数字输入,跳转到不同的页面并实现相应的功能。

package com.vanessa.express;

public class Main {
    private static Views v = new Views();
    private static ExpressDao d = new ExpressDao();
    public static void main(String[] args) {
        v.welcome();
        w:while (true) {
            int menu = v.menu();
            switch (menu) {
                case 0:
                    break w;
                case 1:
                    administrator();
                    break;
                case 2:
                    user();
                    break;
            }
        }
        v.byebye();
    }

    /**
     * 用户各个功能实现
     */
    private static void user() {
        boolean b = true;
        while (b) {
            int number = v.uMenu();
            Express e = d.findByNumber(number);
            if (e == null) {
                v.expressNotExist();
                b = true;
            } else {
                v.printExpress(e);
                v.successPickup();
                d.delete(e);//取件成功后将该快递从快递柜中删除
                b = false;
            }
        }
    }

    /**
     * 管理员各个功能实现
     */
    private static void administrator() {
        while (true){
            int menu = v.aMenu();
            switch (menu){
                case 0: return;//返回上一层
                case 1: {//录入快递
                    Express e1 = v.insert();
                    Express e2 = d.findByCode(e1.getCode());//通过快递单号判断该快递是否已经存在
                    if (e2 == null){
                        d.add(e1);
                        v.printExpress(e1);
                    } else {//该单号快递已经存在快递柜中
                        v.expressExist();
                    }
                }
                break;
                case 2: {//删除快递
                    boolean b = true;
                    while (b) {
                        String code = v.findByCode();//获取快递单号
                        Express e = d.findByCode(code);//在快递数组中通过快递单号查找快递
                        if (e == null) {//不存在该单号快递
                            v.expressNotExist();
                            b = true;
                        } else {
                            v.printExpress(e);
                            int type = v.delete();
                            if (type == 1) {
                                d.delete(e);
                                v.deleteSuccess();
                            }
                            b = false;
                        }
                    }
                    /*Express e = d.findByCode(code);
                    if (e == null){
                        v.expressNotExist();
                    } else {
                        v.printExpress(e);
                        int type = v.delete();
                        if (type == 1) {
                            d.delete(e);
                            v.deleteSuccess();
                        }
                    }*/
                }
                break;
                case 3: {//修改快递
                    boolean b = true;
                    while (b) {
                        String code = v.findByCode();
                        Express e = d.findByCode(code);
                        if (e == null) {
                            v.expressNotExist();
                            b = true;
                        } else {
                            v.update(e);//调用该方法修改快递单号和快递公司
                            v.printExpress(e);
                            b = false;
                        }
                    }
                }
                break;
                case 4: {//查看所有快递
                    Express[][] data = d.all();
                    v.printAll(data);
                }
                break;
            }
        }
  
  1. 遇到的问题
    (1)空指针问题
        问题描述:当快递为空时,调用get方法获取数据进行条件判断时出错。在这里插入图片描述    解决方法:在进行if前添加语句if(data[i][j] !=null)进行判断,可使进入判断语句中的data[i][j]均不为空。
    在这里插入图片描述
        问题描述:在135行代码中,当快递为空时,调用get方法出现。
    在这里插入图片描述
        解决方法:先判断再进行输出。
    在这里插入图片描述
    (2)逻辑问题
        问题描述:在进行删除快递操作时,如果输入单号错误,进入了修改单号操作。
    在这里插入图片描述

    原因:break放在整个操作里面,在中括号之中判断语句未执行到break无法退出,直接进行到下一个case,即修改快递单号的操作中。
    解决方法:将break移至中括号外,待case执行完所有语句后执行。
在这里插入图片描述
5. 进一步完善
    在进行取件操作时,如果输入的取件码是错误的,会返回至身份选择页面,想要实现:当输入取件码错误后,输出提示信息并重新让用户输入取件码。
在这里插入图片描述
    在删除快递操作时,快递信息不存在时返回至上一层。
在这里插入图片描述
    在修改快递操作时,快递信息不存在时返回至上一层。
在这里插入图片描述
    以上使用while循环语句进行即可,创建boolean变量继续判断是否进行下一次循环,如果输入错误,则将boolean变量赋值为true使其进入下一次循环;如果输入正确,则将boolean变量赋值为false,退出循环。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
6. 小总结
    通过该实验的学习过程,对于Java编程规范有了更深的理解,编程的习惯也更规范化。代码仍存在一定的不完善之处,大家共同进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值