JavaSE案例 02——集合综合运用案例 1 需求 实现一个图书馆管理系统后台开发,需要实现以下功能: 1.查看全部书籍。query2.添加书本信息。add3.删除书本信息。delete4.修改书本信息。upd
JavaSE案例 02——集合综合运用案例
1 需求
实现一个图书馆管理系统后台开发,需要实现以下功能:
1.查看全部书籍。query
2.添加书本信息。add
3.删除书本信息。delete
4.修改书本信息。update
5.退出系统:exit
详情书籍如下,仅供参考
书本信息的结构:
类型 书名 价格 作者
言情小说
《西厢记》 99.9 王实甫
《红楼梦》 198.2 曹雪清
武侠小说
《三少爷的剑》 98.2 古龙
《神雕侠侣》 97.2 金庸
2 面向对象思路设计
1.定义一个书本类,书本类中有书,书本类是List橱柜的元素
2.定义一个集合表示图书馆用于存储书本信息数据:Map<String,List<Book>>,key是书本的栏目,values是List橱柜
3.展示操作界面
4.完成相应功能
3 开工
3.1 定义一个书本类
内容:赋予书本类名字,价格,作者的私有属性,并生成无参和有参构造器,以及生成get和set方法
代码
public class Book {
private String name;
private double price;
private String author;
public Book() {
}
public Book(String name, double price, String author) {
this.name = name;
this.price = price;
this.author = author;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
3.2 定义一个集合表示图书馆用于存储书本信息数据
内容:使用Map集合,键是橱柜的栏目类型名称,值是橱柜的List集合对象存储书本信息
代码:
public class BookSystem02 {
//1.定义一个集合表示图书馆用于存储书本信息数据:Map<String,List<Book>>
//使用Map集合,键是橱柜的栏目类型名称,值是橱柜的List集合对象存储书本信息
public static final Map<String, List<Book>> BOOK_STORE = new HashMap<>();
//用Scanner表示系统的扫描器,仅有一个,给他定义成静态的不可变的
public static final Scanner SYS_SCANNER = new Scanner(System.in);
public static void main(String[] args) {
}
}
3.3 展示操作界面
内容:
代码
public static void main(String[] args) {
//2.展示相应界面:独立功能建议封装成方法调用 方便互相之间的逻辑调用
showCommand();
//展示操作界面的命令
}
private static void showCommand() {
System.out.println("================欢迎您进入系统========================");
System.out.println("查看全部书籍。query");
System.out.println("添加书本信息。add");
System.out.println("删除书本信息。delete");
System.out.println("修改书本信息。update");
System.out.println("退出系统:exit");
System.out.print("请您输入您的操作命令:");
String command = SYS_SCANNER.nextLine();
//判断用户的命令是想干啥
switch (command){
case "query":
//查看全部书籍
queryBook();
break;
case "add":
//添加书本信息
addBook();
break;
case "delete":
//删除书本信息
break;
deleteBook();
case "update":
//修改书本信息
updateBook();
break;
case "exit":
//退出系统
System.out.println("退出成功,期待您下次光临!");
System.exit(0);
break;
default:
System.err.println("您的输入有误,请重新确认");
}
showCommand();//递归思想:调用自己
}
}
3.4 实现添加书本信息
内容:
- 如果存在这个书本栏目,只需要拿到它的value后,再把书本对象添加进去
- 如果不存在这个书本栏目,需要从下到上添加
- 把书本对象添加到橱柜List中
- 即新建橱柜List,将书本栏目和橱柜添加进图书馆
代码
//添加书本信息数据
private static void addBook() {
System.out.println("================欢迎您进入添加书本业务========================");
System.out.println("请您输入添加书本的栏目");
String type = SYS_SCANNER.nextLine();
if(BOOK_STORE.containsKey(type)){
List<Book> books = BOOK_STORE.get(type);
System.out.println("请输入您的书本名称:");
String name =SYS_SCANNER.nextLine();
System.out.println("请输入您的书本价格:");
String price =SYS_SCANNER.nextLine();
System.out.println("请输入您的书本作者:");
String author =SYS_SCANNER.nextLine();
//定义一个书本对象封装用户输入的书本信息
Book book = new Book(name,Double.valueOf(price),author);
books.add(book);
}else{
//需要创建新的栏目 ,以及放书的List橱柜
List<Book> books = new ArrayList<>();
System.out.println("请输入您的书本名称:");
String name =SYS_SCANNER.nextLine();
System.out.println("请输入您的书本价格:");
String price =SYS_SCANNER.nextLine();
System.out.println("请输入您的书本作者:");
String author =SYS_SCANNER.nextLine();
//定义一个书本对象封装用户输入的书本信息
Book book = new Book(name,Double.valueOf(price),author);
books.add(book);
//把橱柜和栏目存入到图书馆中
BOOK_STORE.put(type,books);
}
}
- 优化版本
- 抽象出来,只需要对橱柜进行判断即可,重复步骤放最后,最前面用List<Book> books = null指向栏目的橱柜
//添加书本信息数据
private static void addBook() {
System.out.println("================欢迎您进入添加书本业务========================");
System.out.println("请您输入添加书本的栏目");
String type = SYS_SCANNER.nextLine();
//写出来代码很臃肿,因此先定义一个List集合用于指向栏目的橱柜
List<Book> books = null;
//a.判断是否已经存在了这个栏目,如果存在直接加书对象,如果不存在,需要创建新的栏目 ,以及放书的List橱柜
if(BOOK_STORE.containsKey(type)){
books = BOOK_STORE.get(type);//把橱柜交给这个变量
}else{
//需要创建新的栏目 ,以及放书的List橱柜
books = new ArrayList<>();
//把橱柜和栏目存入到图书馆中
BOOK_STORE.put(type,books);
}
System.out.println("请输入您的书本名称:");
String name =SYS_SCANNER.nextLine();
System.out.println("请输入您的书本价格:");
String price =SYS_SCANNER.nextLine();
System.out.println("请输入您的书本作者:");
String author =SYS_SCANNER.nextLine();
//定义一个书本对象封装用户输入的书本信息
Book book = new Book(name,Double.valueOf(price),author);
books.add(book);
System.out.println("您添加在"+type+"下的书本"+book.getName()+"成功");
}
- 再次优化
- 增加了用户输入书本价格的时候不合规导致的数字转换异常的处理机制
private static void addBook() {
System.out.println("================欢迎您进入添加书本业务========================");
System.out.println("请您输入添加书本的栏目");
String type = SYS_SCANNER.nextLine();
//写出来代码很臃肿,因此先定义一个List集合用于指向栏目的橱柜
List<Book> books = null;
//a.判断是否已经存在了这个栏目,如果存在直接加书对象,如果不存在,需要创建新的栏目 ,以及放书的List橱柜
if(BOOK_STORE.containsKey(type)){
books = BOOK_STORE.get(type);//把橱柜交给这个变量
}else{
//需要创建新的栏目 ,以及放书的List橱柜
books = new ArrayList<>();
//把橱柜和栏目存入到图书馆中
BOOK_STORE.put(type,books);
}
System.out.println("请输入您的书本名称:");
String name =SYS_SCANNER.nextLine();
//再套一个死循环
double priceDouble = 0.0;
while (true){
try {
System.out.println("请输入您的书本价格:");
String price =SYS_SCANNER.nextLine();
priceDouble = Double.valueOf(price);
//double priceDouble = Double.valueOf(price);
break;
} catch (Exception e) {
System.out.println("价格格式不对!请重新检查");
}
}
System.out.println("请输入您的书本作者:");
String author =SYS_SCANNER.nextLine();
//定义一个书本对象封装用户输入的书本信息
//Book book = new Book(name,Double.valueOf(price),author);//矛盾转义到上面
Book book = new Book(name,priceDouble,author);//访问不到,把价格定义在外面即可
books.add(book);
System.out.println("您添加在"+type+"下的书本"+book.getName()+"成功");
}
3.5 查看全部书籍
内容:
- 遍历两个集合即可
- 需要考虑Map集合一个元素都没有的情况
代码
private static void queryBook() {
System.out.println("================欢迎您进入查询书本业务========================");
if (BOOK_STORE.size() == 0) {//栏目有,橱柜一本书也没有没事,后面不用遍历,但是一个栏目也没有需要加个判断
System.err.println("您的图书馆一本书都没有,请及时添加书籍。");
} else {
System.out.println("类型\t\t\t\t书名\t\t\t\t价格\t\t\t\t作者");
BOOK_STORE.forEach((type, books) -> {
System.out.println(type);
//再遍历List橱柜
for (Book book : books) {
System.out.println("\t\t\t\t" + book.getName() + "\t\t\t\t" + book.getPrice() + "\t\t\t\t" + book.getAuthor());
}
});
}
}
3.6 修改书本信息
内容:
- while循环和递归的区别:递归整个方法再来一遍,while可以选择需要循环的地方进行循环
- 需要考虑到输入的栏目和书本不存在的情况,或者根本就没有整个Map集合都没有值的情况
代码
private static void updateBook() {
System.out.println("================欢迎您进入查询书本业务========================");
if(BOOK_STORE.size()==0){
System.err.println("您现在根本没有任何栏目可以修改!");
}else{
while (true) {
queryBook();//修改前查下有哪一些书
System.out.println("请输入修改的栏目名称:");
String type = SYS_SCANNER.nextLine();
//考虑没栏目的情况
if (BOOK_STORE.containsKey(type)) {
System.out.println("请输入你需要修改的书本名称");
String searchbook = SYS_SCANNER.nextLine();
List<Book> books = BOOK_STORE.get(type);
for (Book book : books) {
while (true){
//考虑没书名的情况
if(searchbook.equals(book.getName())){
System.out.println("请输入修改书本名称:");
String newname = SYS_SCANNER.nextLine();
System.out.println("请输入修改书本价格:");
String newprice = SYS_SCANNER.nextLine();
System.out.println("请输入修改书本作者:");
String newauthor = SYS_SCANNER.nextLine();
book.setName(newname);
book.setPrice(Double.valueOf(newprice));
book.setAuthor(newauthor);
System.out.println("修改成功");
queryBook();
return;//结束
}else{
System.err.println("您输入的书名不对");
}
}
}
} else {
System.err.println("修改的栏目不存在");
}
}
}
}
- 再抽象一个方法出来
- 独立功能写一个公共方法,也方便的其他方法的调用,组件化
public static Book getBookByTypeAndName(String type,String name){
//1.先提出这本书的橱柜,根据栏目提取它的橱柜
List<Book> books = BOOK_STORE.get(type);
for (Book book : books) {
//如果传进来的书的名称等于遍历出来书的名称,那么就返回这本书
if(book.getName().equals(name)){
return book;
}
}
return null;//没有这本书
}
//修改书本信息
private static void updateBook() {
System.out.println("================欢迎您进入查询书本业务========================");
if(BOOK_STORE.size()==0){
System.err.println("您现在根本没有任何栏目可以修改!");
}else {
queryBook();
while (true) {
System.out.println("请输入需要修改的栏目:");
String type = SYS_SCANNER.nextLine();
//1.判断是否存在这个栏目
if (BOOK_STORE.containsKey(type)) {
while (true) {
//2.请输入要修改的书名
System.out.println("请输入修改书本的名称:");
String name = SYS_SCANNER.nextLine();
//3.该栏目是否存在书本//注意:独立业务功能后续也可能多次使用,也给他封装成方法
Book book = getBookByTypeAndName(type, name);
if (book == null) {
System.err.println("您输入的书名不存在,请重新确认!");//再套一个死循环
} else {
//书名正确了开始修改
System.out.println("请输入修改书本名称:");
String newname =SYS_SCANNER.nextLine();
System.out.println("请输入修改书本价格:");
String newprice =SYS_SCANNER.nextLine();
System.out.println("请输入修改书本作者:");
String newauthor =SYS_SCANNER.nextLine();
//修改
book.setName(newname);
book.setPrice(Double.valueOf(newprice));
book.setAuthor(newauthor);
queryBook();
System.out.println("修改成功,请查看以上信息确认!");
return;//结束修改
}
}
} else {
System.out.println("您输入的栏目不存在,请重新确认!");
//updateBook();//修改完才能走,递归一下,或者直接死循环
}
}
}
}
3.7 删除书本信息
内容:
- 和上面的修改差不多
- 需要的是拿到橱柜List,然后用remove的API删除即可
- 可以调用独立出来的方法getBookByTypeAndName(),在上面有
代码
private static void deleteBook() {
if(BOOK_STORE.size()==0){
System.err.println("您现在根本没有任何栏目可以删除!");
}else {
queryBook();
System.out.println("===================欢迎进入删除书本业务=====================");
while (true) {
System.out.println("请您输入你要删除书本的栏目:");
String type = SYS_SCANNER.nextLine();
//判断是否有栏目
if (BOOK_STORE.containsKey(type)) {
while (true) {
//输入要删除的书
System.out.println("请输入修改书本的名称:");
String name = SYS_SCANNER.nextLine();
//根据栏目和书名去寻找这个栏目中有的书,用之前写好的代码
Book book = getBookByTypeAndName(type, name);
if (book == null) {
System.out.println("您输入的书名不存在,请重新确认!");
} else {
//把橱柜的书取出来,然后删掉
List<Book> books = BOOK_STORE.get(type);
books.remove(book);
System.out.println("删除成功!");
queryBook();
return;
}
}
} else {
System.err.println("您输入的栏目不存在,请重新确认!");
}
}
}
}