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


文章目录


学完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. 返回上级目录

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

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