题目要求
本案例使用 是IO编程,用IO编程存储的是集合的对象,如果用文件的输入输出的话去存取快递单号,取件码,和快递公司在存的时候可以按照每行去存储,在取的时候也可以按照每行去取,然后把取出来的字符按照字符分割去分割,然后调用equals方法去判断取件码快递单号是否相同,但是这样存取快递太麻烦,所以用下边这种方法,直接把快递对象存入集合,然后直接把集合的对象存入文件中,本次实例运用了序列化与反序列化技术。先介绍序列化与反序列化
序列化与反序列化--------向文件里传入对象
import java.io.*;
public class Practice {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// Book bk=new Book("三国演义","讲述了三分天下的局面");
// ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("Text.txt"));
// oos.writeObject(bk);
// oos.close();
ObjectInputStream ois =new ObjectInputStream(new FileInputStream("Text.txt"));
Book o=(Book)ois.readObject();
System.out.println(o.getName()+" "+o.getInfo());
}
}
class Book implements Serializable{
String name;
String info;
//两种方法去给name和info赋值,一种是写构造方法,一种是写setter和getter方法
public Book(String name, String info) {
this.name=name;
this.info=info;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
上面现在该目录下创建一个新的Text文件夹,然后,传入Book对象。但是传入的是我们读不懂的数据
上面的这个例子就是介绍的序列化与反序列化。
然后接下来介绍快递E栈的编写
快递类
import java.io.Serializable;
import java.util.Objects;
public class Express implements Comparable<Express>, Serializable {
private int number; //快递编号
private String company; //快递公司
private int code; //取件码
public Express(int number, String company) {
this.number = number;
this.company = company;
}
public int getNumber() {
return number;
}
public String getCompany() {
return company;
}
public void setNumber(int number) {
this.number = number;
}
public void setCompany(String company) {
this.company = company;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Express express = (Express) o;
return number == express.number;
}
@Override
public int hashCode() {
return Objects.hash(number);
}
@Override
public int compareTo(Express o) {
return Integer.compare(this.number, o.number);
}
}
快递柜的代码
import java.io.*;
import java.util.Random;
import java.util.TreeSet;
public class ExpressLocker {
private TreeSet<Express> expressSet;
private static final String PATH = "express.txt"; //集合存储的文件路径
private ObjectOutputStream oos;
public ExpressLocker() throws IOException {
File file = new File(PATH);
if (file.exists()) {
//数据文件存在,则从文件中读取集合
try (ObjectInputStream ois = new ObjectInputStream((new FileInputStream(PATH)))) {
expressSet = (TreeSet<Express>) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
//无法从文件中读取集合
e.printStackTrace();//输出错误的路径
expressSet = new TreeSet<>();
throw new IOException("无法从数据文件中读取集合");
}
} else
//数据文件不存在,则创建空的集合
expressSet = new TreeSet<>();
}
/**
* 关机操作
*/
public void close() throws IOException {
this.write();
oos.close();
}
/**
* 将集合写入文件
*
* @throws IOException 无法写入数据文件,或者输出流初始化失败
*/
public void write() throws IOException {
//如果输出流未被初始化,则证明是第一次写入,对输出流进行初始化
if (oos == null) {
oos = new ObjectOutputStream(new FileOutputStream(PATH));//这个位置我写的错误
}
//写入对象
oos.writeObject(expressSet);
}
/**
* 根据快递单号查询快递
*
* @param expressNumber 快递单号
* @return 若有则返回查询到的快递, 若没有则返回null
*/
public Express findByNumber(int expressNumber) {
for (Express e : expressSet) {
if (e.getNumber() == expressNumber)
return e;
}
return null;
}
/**
* 根据快递单号查询快递
*
* @param expressCode 快递取件码
* @return 若有则返回查询到的快递, 若没有则返回null
*/
public Express findByCode(int expressCode) {
for (Express e : expressSet) {
if (e.getCode() == expressCode)
return e;
}
return null;
}
/**
* 添加快递
*
* @param express 待添加的快递
* @return 添加结果
*/
public boolean add(Express express) throws IOException {
if (express == null)
return false;
//生成取件码
express.setCode(genCode());
//添加快递
final boolean b = expressSet.add(express);
if (b)
this.write();
return b;
}
/**
* 生成100000-999999之间的取件码
*
* @return 取件码
*/
public int genCode() {
int num; //接收系统生成的随机数
Random random = new Random();
do {
num = random.nextInt(900000) + 100000;
//如果快递柜中没有该取件码的快递,证明新生成的取件码有效
} while (findByCode(num) != null);
return num;
}
/**
* 删除快递
* @param express 待删除的快递
* @return 删除结果
*/
public boolean delete(Express express) throws IOException {
final boolean b = expressSet.remove(express);
if (b)
this.write();//删除成功就写出
return b;
}
public Express[] getExpresses() {
return expressSet.toArray(new Express[this.getSize()]);
}
public int getSize() {
return expressSet.size();
}
}
主类的代码用于调用各个对象和方法,程序执行的入口
import java.io.IOException;
/**
* 作业
* 快递柜
* 调度层
*/
public class Main {
static Views views = new Views(); //视图层
static ExpressLocker locker;
static {
try {
locker = new ExpressLocker();
} catch (IOException e) {
views.errorRead();
e.printStackTrace();
}
}
public static void main(String[] args) {
int i1; //接收用户的输入
Loop1:
while (true) {
//开机总控流程
//开始菜单
i1 = views.menu1();
switch (i1) {
case 1:
//取件
user();
break;
case 2:
//管理员功能
administrator();
break;
case 0:
//退出
try {
locker.close();
} catch (IOException e) {
views.errorWrite();
e.printStackTrace();
}
break Loop1;
}
}
}
/**
* 管理员的操作流程
*/
public static void administrator() {
int i1; //接收用户的输入
while (true) {
i1 = views.administratorMenu();
switch (i1) {
case 0:
//返回上一级
return;
case 1:
//快递录入
addExpress();
break;
case 2:
//删除快递
deleteExpress();
break;
case 3:
//修改快递
changeExpress();
break;
case 4:
//查看所有快递
{
Express[] expresses = locker.getExpresses();
// int num = locker.getIndex();//当前存入的快递数量
int num = locker.getSize();//getSize是一个方法,返回值是集合的大小
views.showAllExpress(expresses, num);
}
}
}
}
/**
* 快递录入
*/
public static void addExpress() {
//输出提示信息,并接收快递单号和快递公司
Express express = views.getExpressNumberAndCompany();
//查询快递单号,是否已经存入该快递
if (locker.findByNumber(express.getNumber()) == null) {
//没有该快递,可以存入
try {
if (locker.add(express)) {
//存入成功,输出快递信息
views.showExpress(express);
} else {
//存入失败,快递柜已经满载
views.alreadyFull();
}
} catch (IOException e) {
views.errorWrite();
e.printStackTrace();
}
} else {
//已经有该快递
views.hasExpress();
}
}
/**
* 删除快递
*/
public static void deleteExpress() {
//输出提示并获取快递单号
int number = views.getExpressNumber();
//查询是否有该快递
Express express = locker.findByNumber(number);
if (express == null) {
//没有该快递
views.noExpress();
} else {
//有该快递,则删除该快递
try {
if (locker.delete(express)) {
//操作成功
views.success();
} else {
//操作失败
views.failed();
}
} catch (IOException e) {
views.errorWrite();
e.printStackTrace();
}
}
}
/**
* 修改快递
*/
public static void changeExpress() {
//输出提示并获取快递单号
int number = views.getExpressNumber();
//查询是否有该快递
Express express = locker.findByNumber(number);
if (express == null) {
//没有该快递
views.noExpress();
} else {
//有该快递,则输出提示信息,并接收新的快递单号和快递公司
Express expressNew = views.getExpressNumberAndCompany();
//删除旧快递
try {
if (locker.delete(express)) {
//操作成功
locker.add(expressNew);
views.success();
} else {
//操作失败
views.failed();
}
} catch (IOException e) {
views.errorWrite();
e.printStackTrace();
}
}
}
/**
* 普通用户的操作流程
*/
public static void user() {
//输出提示信息,并接收取件码
int expressCode = views.getExpressCode();
//查询是否有该快递
Express express = locker.findByCode(expressCode);
if (express != null) {
//有该快递
views.showExpress(express);
//从快递柜中删除该快递
try {
locker.delete(express);
} catch (IOException e) {
views.errorWrite();
e.printStackTrace();
}
} else {
//没有该快递
views.noExpress();
}
}
}
选择功能的界面
import java.util.Scanner;
/**
* 作业:快递柜
* 视图层
*/
public class Views {
Scanner sca = new Scanner(System.in); //用于接收用户在控制台中的输入
public Views() {
}
/**
* 开机一级提示菜单,提示取件功能(普通用户)和管理员,并获取用户输入
*
* @return 用户的输入结果
*/
public int menu1() {
int num; //接收用户的输入
while (true) {
//提示信息
System.out.println("\n欢迎使用");
System.out.println("请选择功能,并输入功能编号:");
System.out.println("1.取件");
System.out.println("2.管理员功能");
System.out.println("0.退出");
//获取用户输入
try {
num = Integer.parseInt(sca.nextLine());
//判断输入是否合法,若不合法则重新输入
if (num < 0 || num > 2) {
System.out.println("\n输入信息有误,请根据提示重新输入");
continue;
}
//输入合法,返回用户的输入值
return num;
} catch (NumberFormatException e) {
//若输入不合法导致转型失败,则重新输入
}
}
}
/**
* 管理员菜单,提示管理员的各种功能,并获取用户的选择
*
* @return 用户的输入结果
*/
public int administratorMenu() {
int num; //接收用户的输入
while (true) {
//提示信息
System.out.println("\n请选择功能,并输入功能编号:");
System.out.println("1.快递录入");
System.out.println("2.删除快递");
System.out.println("3.修改快递");
System.out.println("4.查看所有快递");
System.out.println("0.返回上一级");
//获取用户输入
try {
num = Integer.parseInt(sca.nextLine());
//判断输入是否合法,若不合法则重新输入
if (num < 0 || num > 4) {
System.out.println("\n输入信息有误,请根据提示重新输入");
continue;
}
//输入合法,返回用户的输入值
return num;
} catch (NumberFormatException e) {
//若输入不合法导致转型失败,则重新输入
}
}
}
/**
* 获取快递单号和快递公司
*
* @return 用户输入的快递单号和快递公司对应的快递
*/
public Express getExpressNumberAndCompany() {
int num; //接收用户输入的快递单号
//获取快递单号
while (true) {
System.out.println("\n请输入快递单号:");
try {
num = Integer.parseInt(sca.nextLine());
break;
} catch (NumberFormatException e) {
//若输入不合法导致转型失败,则重新输入
}
}
//获取快递公司,并创建快递
System.out.println("请输入快递公司:");
return new Express(num, sca.nextLine());
}
/**
* 输出快递信息,必须有取件码
*/
public void showExpress(Express express) {
if (express == null)
noExpress();
else
System.out.println("\n快递信息:快递单号: " + express.getNumber()
+ " 快递公司: " + express.getCompany()
+ " 取件码: " + express.getCode());
}
/**
* 快递柜中已经有该快递,输出错误提示信息
*/
public void hasExpress() {
System.out.println("\n该快递已经被存入,请核对快递单号");
}
/**
* 快递柜已经满载,输出错误提示信息
*/
public void alreadyFull() {
System.out.println("\n快递柜已满,无法存入快递");
}
/**
* 获取快递单号
*
* @return 用户输入的快递单号
*/
public int getExpressNumber() {
int num; //接收用户输入的快递单号
//获取快递单号
while (true) {
System.out.println("\n请输入快递单号:");
try {
num = Integer.parseInt(sca.nextLine());
return num;
} catch (NumberFormatException e) {
//若输入不合法导致转型失败,则重新输入
}
}
}
/**
* 没有该快递,输出错误提示信息
*/
public void noExpress() {
System.out.println("\n没有该快递,请核对输入的快递信息");
}
/**
* 操作成功(删除,修改),输出提示信息
*/
public void success() {
System.out.println("\n操作成功");
}
/**
* 操作失败(删除,修改),输出提示信息
*/
public void failed() {
System.out.println("\n操作失败");
}
/**
* 获取取件码
*
* @return 用户输入的取件码
*/
public int getExpressCode() {
int num; //接收用户输入的取件码
//获取取件码
while (true) {
System.out.println("\n请输入取件码:");
try {
num = Integer.parseInt(sca.nextLine());
return num;
} catch (NumberFormatException e) {
//若输入不合法导致转型失败,则重新输入
}
}
}
/**
* 输出所有快递信息
*
* @param expresses 快递柜中的所有快递
* @param num 快递柜中存入的快递数量
*/
public void showAllExpress(Express[] expresses, int num) {
if (expresses == null || num == 0) {
lockerEmpty();
} else {
for (Express express : expresses) {
if (express != null)
showExpress(express);
}
}
}
/**
* 当前快递柜没有快递
*/
public void lockerEmpty() {
System.out.println("当前快递柜没有快递");
}
/**
* 无法从数据文件中读取集合
*/
public void errorRead() {
System.out.println("数据文件损坏,无法从数据文件中读取集合");
}
/**
* 无法将集合写入文件
*/
public void errorWrite() {
System.out.println("数据层结束错误,无法将集合写入文件");
}
}