天天看点

快乐E栈项目实战第四阶段

快乐E栈项目实战第四阶段

文章目录

  • ​​快乐E栈项目实战第四阶段​​
  • ​​1、思路​​
  • ​​2、代码​​
  • ​​3、结果​​

学完Java的IO操作,我们使用文件将快递信息存储起来,这样程序重新启动起来存储的快递信息也不会丢失,暂时不使用序列化进行存储,使用Properties文件进行快递信息存储。

1、思路

快递信息的index转换为字符串作为key值进行存储,快递信息以逗号分隔,然后通过冒号映射对应的数据,即存储到文件中的快递信息如下:

#\u5FEB\u9012\u4FE1\u606F
#Sun Apr 04 15:42:51 CST 2021
96=number\:123,company\:\u987A\u4E30,code\:677491
70=number\:124,company\:\u5706\u901A,code\:638754
20=number\:125,company\:\u4E2D\u901A,code\:990138      

存储的是unicode,需要转换为中文:

#快递信息
#Sun Apr 04 15:42:51 CST 2021
96=number\:123,company\:顺丰,code\:677491
70=number\:124,company\:圆通,code\:638754
20=number\:125,company\:中通,code\:990138      

2、代码

view部分:

package com.xiaoyaoyou.view;

import com.xiaoyaoyou.bean.Express;
import sun.lwawt.macosx.CSystemTray;

import java.util.ArrayList;
import java.util.Scanner;

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

    /**
     *  欢迎
     */
    public void welcome() {
        System.out.println("欢迎使用快乐E栈快递管理系统");
    }

    /**
     *  再见
     */
    public void bye() {
        System.out.println("欢迎下次使用~");
    }

    /**
     * 选择身份菜单
     * @return
     */
    public int menu() {
        System.out.println("请根据提示,输入功能序号:");
        System.out.println("1. 快递员");
        System.out.println("2. 普通用户");
        System.out.println("0. 退出");

        //这里的代码逻辑,相较于nextInt优点在哪?
        //单思考这个方法内的逻辑,没有什么优点
        //但是思考全局,是有优点的:所有方法均使用nextLine,不会因为输入产生冲突,还可以更好的接收到各种类型的数据
        String text = input.nextLine();
        int num = -1;
        try {
            num = Integer.parseInt(text);
        }catch (NumberFormatException e) {
            System.out.println("输入有误,请重新输入");
            return menu();
        }

        if(num < 0 || num > 2) {
            System.out.println("输入有误,请重新输入");
            return menu();
        }
        return num;
    }

    /**
     * 快递员菜单
     * @return
     */
    public int cMenu() {
        System.out.println("请根据提示,输入功能序号:");
        System.out.println("1. 快递录入");
        System.out.println("2. 快递修改");
        System.out.println("3. 快递删除");
        System.out.println("4. 查看所有快递");
        System.out.println("0. 返回上级目录");

        String text = input.nextLine();
        int num = -1;
        try {
            num = Integer.parseInt(text);
        }catch (NumberFormatException e) {
            System.out.println("输入有误,请重新输入");
            return cMenu();
        }

        if(num < 0 || num > 4) {
            System.out.println("输入有误,请重新输入");
            return cMenu();
        }
        return num;
    }

    /**
     * 快递员录入快递
     * @return 包含了快递单号和快递公司的快递对象
     */
    public Express insert() {
        System.out.println("请根据提示,输入快递信息:");
        System.out.println("请输入快递单号:");
        String number = input.nextLine();
        System.out.println("请输入快递公司:");
        String company = input.nextLine();
        Express e = new Express();
        e.setCompany(company);
        e.setNumber(number);
        return e;
    }

    /**
     * 提示用于输入快递单号
     * @return
     */
    public String findByNumber() {
        System.out.println("请根据提示,输入快递信息:");
        System.out.println("请输入要操作的快递单号:");
        String number = input.nextLine();
        return number;
    }

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

    public void printNull() {
        System.out.println("快递不存在,请检查您的输入");
    }

    /**
     * 修改快递信息
     * @param e
     */
    public void update(Express e) {
        System.out.println("请根据提示,输入新的快递单号:");
        String number = input.nextLine();
        if(number == "") {
            update(e);
        }
        System.out.println("请根据提示,输入新的快递公司:");
        String company = input.nextLine();
        if(company == "") {
            update(e);
        }
        e.setNumber(number);
        e.setCompany(company);
    }

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

        if(num < 0 || num > 2) {
            System.out.println("输入有误,请重新输入");
            return delete();
        }
        return num;
    }

    /**
     * 将给定数组的快递信息遍历显示
     * @param es
     */
    public void printAll(ArrayList<Express> es) {
        if(es == null || es.size() == 0) {
            System.out.println("暂无快递");
            return;
        }
        int count = 0;
        for (Express e: es) {
            if(e.getNumber() != null) {
                printExpress(e);
                count++;
            }
        }
        if(count == 0) {
            System.out.println("柜中暂无快递信息");
        }
    }

    /**
     * 用户的菜单
     * @return
     */
    public int uMenu() {
        System.out.println("请根据提示,输入六位取件码:");
        System.out.println("请输入您的取件码");

        String code = input.nextLine();
        int num = -1;
        try {
            num = Integer.parseInt(code);
        }catch (NumberFormatException e) {
            System.out.println("输入有误,请重新输入");
            return uMenu();
        }

        if(num < 100000 || num > 999999) {
            System.out.println("输入有误,请重新输入");
            return uMenu();
        }
        return num;
    }

    public void expressExist() {
        System.out.println("此单号在快递柜中已存在,请勿重复存储");
    }

    public void printCode(Express e) {
        System.out.println("快递的取件码为:"+e.getCode());
    }

    public void success() {
        System.out.println("操作成功");
    }
}      

bean部分:

package com.xiaoyaoyou.bean;

import java.util.Objects;

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

    public Express(String number, String company, int code) {
        this.number = number;
        this.company = company;
        this.code = code;
    }

    @Override
    public String toString() {
        return "number:" + number +
                ",company:" + company +
                ",code:" + code;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass() || number == null) return false;
        Express express = (Express) o;
        return number.equals(express.number);
    }

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

    public Express() {
    }

    public String getNumber() {
        return number;
    }

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

    public String getCompany() {
        return company;
    }

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

    public int getCode() {
        return code;
    }

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

dao数据操作部分:

package com.xiaoyaoyou.dao;

import com.xiaoyaoyou.bean.Express;

import java.io.*;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Random;

public class ExpressDao {
    private ArrayList<Express> data = null;
    Properties properties = new Properties();
    public FileOutputStream fileOutputStream = null;
    Reader reader = null;
    //当前存储的快递数(空间换时间)
    private int size;
    {
        data = new ArrayList<Express>();
        for(int i = 1; i <= 100; i++) {
            data.add(new Express());
        }

        try {
            File file = new File("express.txt");
            if(!file.exists()) {
                file.createNewFile();
            }
            reader = new FileReader("express.txt");
            try {
                properties.load(reader);
                for (int i = 1; i <= 100; i++) {
                    String value = properties.getProperty(i+"");
                    if(value != null) {
                        System.out.println(value);
                        getExpressInfo(value, data.get(i));
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void getExpressInfo(String str, Express express) {
        String[] ss = str.split(",");
        for (int i = 0; i < ss.length; i++) {
            String[] ss2 = ss[i].split(":");
            switch (i) {
                case 0:
                    express.setNumber(ss2[1]);
                    break;
                case 1:
                    try {
                        express.setCompany(ss2[1]);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                    break;
                case 2:
                    try {
                        express.setCode(Integer.parseInt(ss2[1]));
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                    break;
            }
        }
    }

    private Random random = new Random();

    /**
     * 用于存储快递
     * @param e
     * @return
     */
    public boolean add(Express e) {
        if(size == 100) {
            return false;
        }
        //1. 随机生成ArrayList的下标
        int index = -1;

        while (true) {
            index = random.nextInt(100);
            if (data.get(index).getNumber() == null) {
                //此位置无快递
                break;
            }
        }
        //2. 取件码
        int code = randomCode();
        e.setCode(code);
        data.set(index, e);
        size++;
        saveToFile();

        return true;
    }

    public void saveToFile() {
        properties.clear();
        for (Express express: data) {
            if(express.getNumber() != null) {
                properties.put(data.indexOf(express) + "", express.toString());
                System.out.println(express.getNumber());
            }
        }
        try {
            fileOutputStream = new FileOutputStream("express.txt");
            properties.store(fileOutputStream, "快递信息");
            fileOutputStream.flush();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

    /**
     * 生成取件码(模板方法设计模式)
     * @return
     */
    private int randomCode() {
        while (true){
            int code = random.nextInt(900000)+100000;
            Express e = findByCode(code);
            if(e == null) {
                return code;
            }
        }
    }

    /**
     * 根据快递单号查询快递
     * @param number
     * @return 查询的结果,查询失败时返回null
     */
    public Express findByNumber(String number) {
        Express e = new Express();
        e.setNumber(number);
        for (Express v: data) {
            if(e.equals(v)) {
                return v;
            }
        }

        return null;
    }

    /**
     * 根据取件码查询快递
     * @param code 要查询的取件码
     * @return 查询的结果,查询失败时返回null
     */
    public Express findByCode(int code) {
        for (Express e: data) {
            if (e != null) {
                if (e.getCode() == code) {
                    return e;
                }
            }
        }
        return null;
    }


    /**
     * 多余的操作,为了mvc更圆润
     * @param oldExpress
     * @param newExpress
     */
    public void update(Express oldExpress, Express newExpress) {
        saveToFile();
    }

    /**
     * 删除快递
     * @param e
     */
    public void delete(Express e) {
        if (data.isEmpty()) {
            return;
        }
        for (Express v: data) {
            if(e.getNumber() == v.getNumber()) {
                e.setCode(0);
                e.setCompany(null);
                e.setNumber(null);
                size--;
                break;
            }
        }

        saveToFile();
        return ;
    }

    public ArrayList<Express> findAll() {
        return data;
    }
}      

main调用控制部分:

package com.xiaoyaoyou.main;

import com.xiaoyaoyou.bean.Express;
import com.xiaoyaoyou.dao.ExpressDao;
import com.xiaoyaoyou.view.Views;

import java.util.ArrayList;

public class CourierClient {
    private ExpressDao dao;
    private Views v;
    public void CourierClient() {
    }

    public CourierClient(ExpressDao dao, Views v) {
        this.dao = dao;
        this.v = v;
    }

    public ExpressDao getDao() {
        return dao;
    }

    public void setDao(ExpressDao dao) {
        this.dao = dao;
    }

    public Views getV() {
        return v;
    }

    public void setV(Views v) {
        this.v = v;
    }

    public void select() {
        while (true) {
            int menu = v.cMenu();
            switch (menu) {
                case 0:
                    return;
                case 1:
                    saveExpress();
                    break;
                case 2:
                    updateExpress();
                    break;
                case 3:
                    deleteExpress();
                    break;
                case 4:
                    queryExpress();
                    break;
            }
        }
    }

    public void saveExpress() {
        //1、提示输入快递信息
        Express e = v.insert();
        //2、此快递是否已经存储过
        Express e2 = dao.findByNumber(e.getNumber());
        //3、存储快递
        if (e2 != null) {
            //单号在快递柜中已存在
            v.expressExist();
            return;
        }

        //未存储过,
        dao.add(e);
        v.printExpress(e);
    }

    public void updateExpress() {
        //1、提示输入快递信息
        String number = v.findByNumber();
        //2、查找数据
        Express e = dao.findByNumber(number);
        Express e2 = e;
        //3、打印快递信息
        if (e == null) {
            v.printNull();
            return;
        }

        v.printExpress(e);
        //4、提示修改
        v.update(e2);
        dao.update(e, e2);
        v.printExpress(e2);
    }

    public void deleteExpress() {
        //1、输入快递单号
        String number = v.findByNumber();
        //2、查找快递对象
        Express e = dao.findByNumber(number);
        if(e == null) {
            v.printNull();
            return;
        }

        v.printExpress(e);
        int type = v.delete();
        if(type == 1) {
            dao.delete(e);
            v.success();
        }
    }

    public void queryExpress() {
        ArrayList<Express> all = dao.findAll();
        v.printAll(all);
    }
}      
package com.xiaoyaoyou.main;

import com.xiaoyaoyou.bean.Express;
import com.xiaoyaoyou.dao.ExpressDao;
import com.xiaoyaoyou.view.Views;

public class UserClient {
    private ExpressDao dao;
    private Views v;

    public UserClient() {
    }

    public UserClient(ExpressDao dao, Views v) {
        this.dao = dao;
        this.v = v;
    }

    public ExpressDao getDao() {
        return dao;
    }

    public void setDao(ExpressDao dao) {
        this.dao = dao;
    }

    public Views getV() {
        return v;
    }

    public void setV(Views v) {
        this.v = v;
    }

    public void getExpress() {
        //1、获取取件码
        int code = v.uMenu();
        //2、根据取件码取出快递
        Express e = dao.findByCode(code);
        if (e == null) {
            v.printNull();
        } else {
            v.success();
            v.printExpress(e);
            dao.delete(e);
        }
    }
}      
package com.xiaoyaoyou.main;

import com.xiaoyaoyou.dao.ExpressDao;
import com.xiaoyaoyou.view.Views;

import java.io.IOException;

public class Main {
    //初始化视图对象
    private static Views v = new Views();
    //初始化dao对象
    private static ExpressDao dao = new ExpressDao();

    private static CourierClient cClient;
    private static UserClient uClient;

    public static void main(String[] args) {
        init();

        while (run()) {
        }

        destroy();
    }

    /**
     * 初始化
     */
    private static void init() {
        //1.欢迎
        v.welcome();

        cClient = new CourierClient(dao, v);
        uClient = new UserClient(dao, v);
    }

    /**
     * 主进程运行流程
     * @return
     */
    private static boolean run() {
        //2.弹出身份选择菜单
        int menu = v.menu();
        switch (menu) {
            case 0:
                //退出
                return false;
            case 1:
                //快递员
                cClient.select();
                break ;
            case 2:
                //用户
                uClient.getExpress();
                break ;
        }

        return true;
    }

    /**
     * 资源释放
     */
    private static void destroy() {
        //释放资源
        try {
            dao.fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        v.bye();
    }
}      

3、结果

欢迎使用快乐E栈快递管理系统
请根据提示,输入功能序号:
1. 快递员
2. 普通用户
0. 退出
1
请根据提示,输入功能序号:
1. 快递录入
2. 快递修改
3. 快递删除
4. 查看所有快递
0. 返回上级目录
1
请根据提示,输入快递信息:
请输入快递单号:
123
请输入快递公司:
顺丰
123
快递信息如下:
快递公司:顺丰,快递单号:123,取件码:928922
请根据提示,输入功能序号:
1. 快递录入
2. 快递修改
3. 快递删除
4. 查看所有快递
0. 返回上级目录
1
请根据提示,输入快递信息:
请输入快递单号:
124
请输入快递公司:
圆通
123
124
快递信息如下:
快递公司:圆通,快递单号:124,取件码:194236
请根据提示,输入功能序号:
1. 快递录入
2. 快递修改
3. 快递删除
4. 查看所有快递
0. 返回上级目录
1
请根据提示,输入快递信息:
请输入快递单号:
125
请输入快递公司:
申通
125
123
124
快递信息如下:
快递公司:申通,快递单号:125,取件码:259180
请根据提示,输入功能序号:
1. 快递录入
2. 快递修改
3. 快递删除
4. 查看所有快递
0. 返回上级目录
2
请根据提示,输入快递信息:
请输入要操作的快递单号:
124
快递信息如下:
快递公司:圆通,快递单号:124,取件码:194236
请根据提示,输入新的快递单号:
125
请根据提示,输入新的快递公司:
顺达
125
123
125
快递信息如下:
快递公司:顺达,快递单号:125,取件码:194236
请根据提示,输入功能序号:
1. 快递录入
2. 快递修改
3. 快递删除
4. 查看所有快递
0. 返回上级目录
3
请根据提示,输入快递信息:
请输入要操作的快递单号:
125
快递信息如下:
快递公司:申通,快递单号:125,取件码:259180
是否确认删除?
1. 确认删除
2. 取消操作
0. 退出
1
123
125
操作成功
请根据提示,输入功能序号:
1. 快递录入
2. 快递修改
3. 快递删除
4. 查看所有快递
0. 返回上级目录
0
请根据提示,输入功能序号:
1. 快递员
2. 普通用户
0. 退出
2
请根据提示,输入六位取件码:
请输入您的取件码
194236
操作成功
快递信息如下:
快递公司:顺达,快递单号:125,取件码:194236
123
请根据提示,输入功能序号:
1. 快递员
2. 普通用户
0. 退出
1
请根据提示,输入功能序号:
1. 快递录入
2. 快递修改
3. 快递删除
4. 查看所有快递
0. 返回上级目录
4
快递信息如下:
快递公司:顺丰,快递单号:123,取件码:928922
请根据提示,输入功能序号:
1. 快递录入
2. 快递修改
3. 快递删除
4. 查看所有快递
0. 返回上级目录