还记得之前的图书管理吗?学习了集合以后,使用集合来进行图书信息的存储吧!(新增IO技术,存储数据到本地文件,下次登陆的时候就可以进行数据载入,使得数据永久存储,请查看我的这一篇博文:图书管理系统的IO优化)
一、功能概述:
1.管理员登陆
2.图书管理
2.1图书新增
2.2图书修改
2.3图书删除
2.4根据图书名称模糊查找图书
2.5查看所有图书(三种排序)
2.5.1价格从高到低排序
2.5.2价格从低到高排序
2.5.3新旧排序(按出版日期排序)
二、任务分析:
1.登陆系统主要使用equals方法进行判断,可以使用一个while(true)循环重复登陆,账户与密码正确就break跳出循环
2.图书的管理是大头,有许多知识点的使用,并且特别的注意各种方法的使用正确
2.1图书新增,得使用异常处理try-catch,并且判断输入的年月是否合理,合理就存入集合即可
2.2图书修改,得使用户输入书名、符合规范的年月日,匹配上就可以进行修改,修改的年月价格也得是符合规范的
2.3图书删除,得使用户输入书名、符合规范的年月日,匹配上就可以进行删除
2.4根据书名模糊查找,是比较生硬的一块,主要涉及的就是模糊匹配的知识点。找到符合规范的图书数据就把它存入一个新的集合,最后进行遍历输出,输出以后记得清空新的那一个集合,便于下次存储
2.5查看所有图书,它的三个子类的原理都是一样的,只要弄明白其中一个就可以全部完成。考虑到不能使用TreeSet进行排序(重复的数据自动忽略),就不使用TreeSet进行数据的自动排序,使用冒泡排序操作集合即可。把数据从存储的集合里面复制一份存在一个全新的集合,使用集合的get,add,remove来操作数据,值得注意的是当年份相同的时候就得判断月份了。
三、代码部分
很多部分我都是使用的while(true)死循环,对于递归的方法不是很熟悉。
1.创建Book类
这一部分没有任何逻辑,创建完就可以了。
public class Book{
//创建图书属性:书名booklist、书的价格price、出版的年publishYear、出版的月publishMonth
private String booklist;
private double pirce;
private int publishMonth;
private int publishYear;
//生成构造方法、toString(),getter/setter方法
public Book() {
}
@Override
public String toString() {
return "Book{" +
"booklist='" + booklist + '\'' +
", pirce=" + pirce +
", publishMonth=" + publishMonth +
", publishYear=" + publishYear +
'}';
}
public String getBooklist() {
return booklist;
}
public void setBooklist(String booklist) {
this.booklist = booklist;
}
public double getPirce() {
return pirce;
}
public void setPirce(double pirce) {
this.pirce = pirce;
}
public int getPublishMonth() {
return publishMonth;
}
public void setPublishMonth(int publishMonth) {
this.publishMonth = publishMonth;
}
public int getPublishYear() {
return publishYear;
}
public void setPublishYear(int publishYear) {
this.publishYear = publishYear;
}
}
2.登陆LogIn类
初始化账户和密码,使用equals()方法判断用户输入的是否一致。使用一个while(true)的死循环,指直到用户输入完全正确就break跳出循环即可。
public class LogIn {
Scanner input = new Scanner(System.in);
//自定义账户名和密码,都设置为String类型
private String count = "admin";
private String password = "123";
//生成equals和hashCode方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LogIn logIn = (LogIn) o;
return Objects.equals(count, logIn.count) &&
Objects.equals(password, logIn.password);
}
@Override
public int hashCode() {
return Objects.hash(count, password);
}
//生成无参构造方法
public LogIn() {
}
//值定义log方法
public void log(){
while(true){
System.out.println("请输入账户名:");
//使用input.nextLine()接收数据不会出错
String countIn = input.nextLine();
System.out.println("请输入密码:");
String passwordIn = input.nextLine();
//调用equals方法判断是否登陆重成功,这一点我也有一点懵逼
if(count.equals(countIn) && password.equals(passwordIn)){
System.out.println("登陆成功!");
break;
}else{
System.out.println("账户/密码错误,请重新操作");
}
}
}
}
3.图书管理Librarin类
这一部分是最难且最精华的部分,涉及很多的细节和知识点。为了减少工作量我也就不使用创建多个类了,全部功能就放在Librarin类里面了,有想尝试放在其他类里面的可以试一试。
3.1Librarin类分析
涉及到异常处理try-catch的使用,ArrayList集合的add(),remove(),get()等常用的方法和细节,遍历foreach()的用法,Calendar类的使用,冒泡排序以及对集合存储的数据顺序的操作,switch()分支语句的充分使用等。
另外值得一提的一点就是关于ArrayList集合的线程不安全问题(有不了解线程不安全问题的小伙伴可以去看我专门提到的线程不安全那一节),我们先看一下那一段代码:
Book temp1;
Book temp2;
for(int i=0;i<looklist.size()-1;i++){
for(int j=0;j<looklist.size()-1-i;j++){
if(looklist.get(j).getPirce() < looklist.get(j+1).getPirce()){
//这里会不会有bug,ArrayList线程不安全?
temp1 = looklist.get(j);
temp2 = looklist.get(j+1);
looklist.remove(j);
looklist.add(j,temp2);
looklist.remove(j+1);
looklist.add(j+1,temp1);
}
}
}
在使用冒泡排序的时候不确定ArrayList集合会不会先执行looklist.add(j,temp2)再执行looklist.remove(j),如果系统出现执行顺序问题就会导致冒泡排序失败,导致新的集合里面的数据丢失,俗称bug。而目前经过我多次进行测试,未出现我上面提到的bug问题,这里希望遇见一位大佬指点指点!
3.2Librarin类代码
public class Librarin {
Scanner input = new Scanner(System.in);
//新增图书
public void add(ArrayList<Book> arrayList){
//创建Librarin,Book对象
Librarin lib = new Librarin();
Book book = new Book();
Scanner input = new Scanner(System.in);
//提示并且获取图书名称
System.out.println("请输入图书名称:");
String booklist = input.nextLine();
//获取图书价格并且判断输入的价格是否合理
System.out.println("请输入图书价格");
String p = input.nextLine();
//用于判断是否符合要求
boolean x = true;
double price = -1;
try{
price = Double.parseDouble(p);
}catch (NumberFormatException e){
System.out.println("价格输入有误,请重新操作");
//不符合要求,x = false
x = false;
}if(price < 0){
System.out.println("价格不能小于0,请重新操作");
x = false;
}
if(x == true) {
boolean ym = true;
System.out.println("请输入图书出版的年份:");
String y = input.nextLine();
System.out.println("请输入图书出版的月份:");
String m = input.nextLine();
int year = -1;
int mon = -1;
try {
year = Integer.parseInt(y);
mon = Integer.parseInt(m);
} catch (NumberFormatException e) {
System.out.println("输入有误,请重新操作");
}
//判断输入的年月是否再合理范围
if ((year>1000 && year<lib.getSystemYear()) && (mon>0 && mon<=12)) {
}else if(year == lib.getSystemYear() && (mon>0 && mon<=12)){
if(mon <= lib.getSystemMonth()){
}
}else{
System.out.println("输入的年份/月份不合理请重新操作");
ym = false;
}
if(ym == true){
//以上全部操作合理以后把数据存入book
book.setBooklist(booklist);
book.setPirce(price);
book.setPublishYear(year);
book.setPublishMonth(mon);
//把数据存入集合
arrayList.add(book);
System.out.println("该图书存储成功!");
}
}
}
//修改图书信息
public void chang(ArrayList<Book> arrayList){
Book book1 = new Book();
if(arrayList.size() == 0){
System.out.println("还未存储图书,请重新操作");
}else {
//获取系统的年月
int yearSystem = getSystemYear();
int monSystem = getSystemMonth();
boolean b = false;
System.out.println("请输入需要修改的图书的名称:");
String booklist = input.nextLine();
System.out.println("请输入需要修改的图书的出版年份");
String y = input.nextLine();
System.out.println("请输入需要修改的图书的出版月份");
String m = input.nextLine();
int year = -1;
int mon = -1;
try {
year = Integer.parseInt(y);
mon = Integer.parseInt(m);
} catch (NumberFormatException e) {
System.out.println("输入的年份/月份有误,请重新操作");
}
if ((year > 1000 && year < yearSystem) && (mon > 0 || mon <= 12)) {
b = true;
} else if ((year == yearSystem) && (mon > 0 && mon <= monSystem)) {
b = true;
}else {
System.out.println("未找到匹配信息,请重新操作");
}
if (b == true) {
for (int i = 0; i < arrayList.size(); i++) {
//获取集合指定元素
book1 = arrayList.get(i);
if ((book1.getBooklist().equals(booklist)) && (book1.getPublishYear() == year)
&& (book1.getPublishMonth() == mon)) {
//输入的图书名称和年月符合,进入修改
System.out.println("需要修改的图书:"+arrayList.get(i));
System.out.println("请选择需要修改的选项:");
System.out.println("1.图书名称\n2.出版年份\n3.出版月份\n4.价格\n0.退出修改");
String index = input.nextLine();
switch (index) {
case "0":
break;
case "1": {
System.out.println("请输入修改后的图书名称");
String booklistChange = input.nextLine();
book1.setBooklist(booklistChange);
//修改完成以后删除修改前的数据
arrayList.remove(i);
//存入原来的位置
arrayList.add(i,book1);
System.out.println("图书名称修改成功!");
System.out.println("修改后的图书信息为:"+arrayList.get(i));
break;
}
case "2": {
System.out.println("请输入修改后的年份");
String yIn = input.nextLine();
int yearIn = -1;
try {
yearIn = Integer.parseInt(yIn);
} catch (NumberFormatException e) {
System.out.println("年份输入有误请重新操作");
}
if (yearIn > 1000 && yearIn <= getSystemYear()) {
book1.setPublishYear(yearIn);
arrayList.remove(i);
arrayList.add(i,book1);
System.out.println("图书年份修改成功");
System.out.println("修改后的图书信息为:"+arrayList.get(i));
} else {
System.out.println("年份输入有误请重新操作");
}
break;
}
case "3": {
System.out.println("请输入修改后的月份");
String mIn = input.nextLine();
int monIn = -1;
try {
monIn = Integer.parseInt(mIn);
} catch (NumberFormatException e) {
System.out.println("月份输入有误请重新操作");
}
if (((monIn > 0 && monIn <= 12) && (book1.getPublishYear() < getSystemYear()))
|| ((monIn > 0 && monIn <= getSystemMonth()) &&
(book1.getPublishYear() == getSystemYear()))) {
//符合年月要求,进行修改
book1.setPublishMonth(monIn);
arrayList.remove(i);
arrayList.add(i,book1);
System.out.println("图书年份修改成功");
System.out.println("修改后的图书信息为:"+arrayList.get(i));
} else {
System.out.println("月份输入有误请重新操作");
}
break;
}
case "4": {
System.out.println("请输入修改后的价格:");
String p = input.nextLine();
int price = -1;
try {
price = Integer.parseInt(p);
} catch (NumberFormatException e) {
System.out.println("价格输入有误,请重新操作");
}
if (price < 0) {
System.out.println("价格输入有误,请重新操作");
} else {
book1.setPirce(price);
arrayList.remove(i);
arrayList.add(i,book1);
System.out.println("图书价格修改成功!");
System.out.println("修改后的图书信息为:"+arrayList.get(i));
}
break;
}
default:
System.out.println("输入有误请重新操作");
break;
}
//查找到指定数据就break该循环,不再进行查找
break;
}
if (i == arrayList.size() - 1) {
System.out.println("未找到指定图书,请重新操作");
break;
}
}
}
}
}
//删除
public void delete(ArrayList<Book> arrayList){
Book book2 = new Book();
if(arrayList.size() == 0){
System.out.println("还未存储图书,请重新操作");
}else{
int yearSystem = getSystemYear();
int monSystem = getSystemMonth();
boolean b = false;
System.out.println("请输入需要删除的图书的名称:");
String booklist = input.nextLine();
System.out.println("请输入需要删除的图书的出版年份");
String y = input.nextLine();
System.out.println("请输入需要删除的图书的出版月份");
String m = input.nextLine();
int year = -1;
int mon = -1;
try{
year = Integer.parseInt(y);
mon = Integer.parseInt(m);
}catch (NumberFormatException e){
System.out.println("输入的年份/月份有误,请重新操作");
}if((year>1000 && year<yearSystem) && (mon>0 || mon<=12)){
b = true;
}else if((year == yearSystem) && (mon>0 && mon<=monSystem)){
b = true;
}if(b == true) {
for (int i = 0; i < arrayList.size(); i++) {
book2 = arrayList.get(i);
if ((book2.getBooklist().equals(booklist)) && (book2.getPublishYear() == year)
&& (book2.getPublishMonth() == mon)){
System.out.println(arrayList.remove(i)+"\n以被删除成功!");
break;
}
if(i == arrayList.size()-1){
System.out.println("未找到指定图书,请重新操作");
break;
}
}
}
}
}
//根据图书名称模糊查找
public void search(ArrayList<Book> arrayList,ArrayList<Book> arraySearch){
if(arrayList.size() == 0){
System.out.println("还未存储过图书,请重新操作");
}else {
System.out.println("请输入您需要查找的图书名称:");
String lookBook = input.nextLine();
//模糊查找精华--注意详细看我的专门说模糊匹配的博客
Pattern pattern = Pattern.compile(lookBook,Pattern.CASE_INSENSITIVE);
for(int i=0;i<arrayList.size();i++){
Matcher matcher = pattern.matcher(arrayList.get(i).getBooklist());
if(matcher.find()){
//把找到的图书放入arraySearch集合
arraySearch.add(arrayList.get(i));
}
}
if(arraySearch.size() == 0){
System.out.println("为找到相关图书,请重新操作");
}else {
Book book = new Book();
System.out.println("查找到的图书有:");
for(int i=0;i<arraySearch.size();i++){
book = arraySearch.get(i);
System.out.println((1+i)+".\t"+book);
}
//输出以后清空存储模糊查找图书的集合
arraySearch.clear();
}
}
}
//查看所有图书
public void seeAll(ArrayList<Book> arrayList, ArrayList<Book> looklist){
if(arrayList.size() == 0){
System.out.println("还未存储图书,请重新操作");
}else{
Book book = new Book();
//把arrayList里面的数据全部复制到looklist里面
for(Book a:arrayList){
book = a;
looklist.add(book);
}
System.out.println("请输入查看方式的选项:");
System.out.println("1.价格从高到低查看\n2.价格从低到高查看\n3.新到旧查看\n4.随即查看\n0.退出查看");
String text = input.nextLine();
int index = -1;
try{
index = Integer.parseInt(text);
}catch (NumberFormatException e){
System.out.println("输入有误请重新操作");
}if(index >= 0 && index <= 4){
switch (index){
case 0:
break;
case 1:{
//冒泡排序,price大的在前
Book temp1;
Book temp2;
for(int i=0;i<looklist.size()-1;i++){
for(int j=0;j<looklist.size()-1-i;j++){
if(looklist.get(j).getPirce() < looklist.get(j+1).getPirce()){
//这里会不会有bug,ArrayList线程不安全?
temp1 = looklist.get(j);
temp2 = looklist.get(j+1);
looklist.remove(j);
looklist.add(j,temp2);
looklist.remove(j+1);
looklist.add(j+1,temp1);
}
}
}
for (Book l:looklist) {
System.out.println(l);
}
//遍历结束以后情况集合,便于下次存储
looklist.clear();
break;
}
case 2:{
//冒泡排序,price小的在前
Book temp1;
Book temp2;
for(int i=0;i<looklist.size()-1;i++){
for(int j=0;j<looklist.size()-1-i;j++){
if(looklist.get(j).getPirce() > looklist.get(j+1).getPirce()){
temp1 = looklist.get(j);
temp2 = looklist.get(j+1);
looklist.remove(j);
looklist.add(j,temp2);
looklist.remove(j+1);
looklist.add(j+1,temp1);
}
}
}
for (Book l:looklist) {
System.out.println(l);
}
looklist.clear();
break;
}
case 3:{
//冒泡排序,年份大的在前,若年份相同,月份大的在前
Book temp1;
Book temp2;
for(int i=0;i<looklist.size();i++){
for(int j=0;j<looklist.size()-1-i;j++){
if((looklist.get(j).getPublishYear() < looklist.get(j+1).getPublishYear())
|| ((looklist.get(j).getPublishYear() == looklist.get(j+1).getPublishYear())
&& (looklist.get(j).getPublishMonth() < looklist.get(j+1).getPublishMonth()))){
temp1 = looklist.get(j);
temp2 = looklist.get(j+1);
looklist.remove(j);
looklist.add(j,temp2);
looklist.remove(j+1);
looklist.add(j+1,temp1);
}
}
}
for (Book l:looklist) {
System.out.println(l);
}
looklist.clear();
break;
}
case 4:{
for (Book a:arrayList) {
System.out.println(a);
}
break;
}
default:
System.out.println("输入有误,请重新操作");
break;
}
}else {
System.out.println("您的输入有误,请重新操作");
}
}
}
//获取系统的年份
public int getSystemYear(){
Calendar date = Calendar.getInstance();
int year = Integer.valueOf(date.get(Calendar.YEAR));
return year;
}
//获取系统月份
public int getSystemMonth(){
Calendar date = Calendar.getInstance();
int month = Integer.valueOf(date.get(Calendar.MONTH));
return month;
}
}
4.Main函数部分
功能都完善了就得调用
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//创建集合用于存储图书的数据
ArrayList<Book> arrayList = new ArrayList<>();
//存储模糊查找的图书数据
ArrayList<Book> arraySearch = new ArrayList<>();
//存储指定排序后的图书数据
ArrayList<Book> looklist = new ArrayList<>();
//创建Librarin、LogIn、Main的对象
Librarin lib = new Librarin();
LogIn log = new LogIn();
Main m = new Main();
//调用welcom方法
m.welcome();
//进入登陆界面
log.log();
//boolean类型的bool用于判断输入的主菜单选项是否符合要求
boolean bool = true;
//使用whiel(true)死循环
p:while (true){
System.out.println("输入您的选项");
System.out.println("1.图书新增\n2.图书修改\n3.图书删除\n" +
"4.根据图书名称模糊查找图书\n5.查看所有图书\n0.退出");
//全局使用input.nextLine()接收数据,避免输入错误
String index = input.nextLine();
int num = -1;
//使用try-catch处理异常
try{
num = Integer.parseInt(index);
}catch (NumberFormatException e){
System.out.println("输入有误,请重新操作");
//不符合要求,bool = false
bool =false;
}if(num<0 || num>5){
System.out.println("输入有误,请重新操作");
//不符合要求,bool = false
bool = false;
}
if(bool == true){
switch (num){
//输入的数据符合要求,进入分支语句
case 1:
//图书新增
lib.add(arrayList);
break;
case 2:
//图书修改
lib.chang(arrayList);
break;
case 3:
//图书删除
lib.delete(arrayList);
break;
case 4:
//根据图书名称模糊查找图书
lib.search(arrayList,arraySearch);
break;
case 5:
//根据要求查看图书
lib.seeAll(arrayList,looklist);
break;
default:
//不使用递归,因为个人对递归理解不深,有大佬可以进行指导!
//都不符合直接接受死循环,重新操作
break p;
}
}
}
//调用bey()方法
m.bye();
}
//无参构造方法
public Main() {
}
//自定义welcome(),bey()方法
public void welcome(){
System.out.println("欢迎使用xx图书管理系统");
}
public void bye(){
System.out.println("感谢您的使用,期待下次再见!");
}
}