当前位置: 首页 > news >正文

Java--图书管理系统(简易版优化)

https://blog.csdn.net/2401_84024092/article/details/147804115?fromshare=blogdetail&sharetype=blogdetail&sharerId=147804115&sharerefer=PC&sharesource=2401_84024092&sharefrom=from_link

✨在上个文章中我们介绍了图书管理系统📖,但是功能并不是很齐全,所以在本篇文章中,我又增加了几个功能:

为了方便大家阅读,已经把完整的代码放到下面啦!如果时第一次看到本篇文章的伙伴,可以先点上面链接看详细讲解版本🎊

1.根据用户的喜好,推荐相应类型的书籍

2.检查是否有逾期书籍,并将检查时间与借书时间保存文本文件中

3.当查找书目时,仅输入“西”或“西游”或“游记”就能找到《西游记》(模糊匹配)

1.library包

1.1Book类

package library;
//增加代码
import java.time.LocalDate;
//一本书
public class Book {//现实世界的书private String name;private String author;private String type;private double price;private boolean isBorrowed;// 增加代码private LocalDate borrowDate; // 借阅日期private LocalDate dueDate; // 应归还日期public Book(String name, String author, String type, double price){this.name=name;this.author=author;this.type=type;this.price=price;this.isBorrowed=false;}//alt+ins自动生成
//get,set方法可以随时更改属性,但是构造方法只能初始化一次//增加代码public LocalDate getBorrowDate() {return borrowDate;}public void setBorrowDate(LocalDate borrowDate) {this.borrowDate = borrowDate;}public LocalDate getDueDate() {return dueDate;}public void setDueDate(LocalDate dueDate) {this.dueDate = dueDate;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getType() {return type;}public void setType(String type) {this.type = type;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public boolean isBorrowed() {return isBorrowed;}public void setBorrowed(boolean borrowed) {isBorrowed = borrowed;}@Overridepublic String toString() {//当执行打印操作时会默认调用return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", type='" + type + '\'' +", price=" + price +", isBorrowed=" + (isBorrowed?"已借出":"未借出") +'}';}
}

1.2BookList类

 

package library;public class BookList {private Book[] books=new Book[1024];//此数组中每个类型都是Book类类型//长度不方便灵活调整,预先创造大空间//把booklist想象为一个书架,书架总共有1024个位置,不能修改大小,所以设置为private//长度不方便灵活调整,预先创造大空间private int size =0;//有效元素public BookList() {books[0] = new Book("西游记", "吴承恩", "古典小说", 100);//books[0]中存放的是一组实例对象books[1] = new Book("红楼梦", "曹雪芹", "古典小说", 90);books[2] = new Book("高等数学", "高斯", "数学", 40);books[3] = new Book("Java入门", "詹姆斯高斯林", "计算机", 70);books[4] = new Book("红楼梦", "曹雪芹", "古典小说", 90);books[5] = new Book("三体", "刘慈欣", "科幻小说", 65);books[6] = new Book("Python编程", "Eric Matthes", "计算机", 75);books[7] = new Book("活着", "余华", "文学", 50);books[8] = new Book("C++ Primer", "Stanley Lippman", "计算机", 120);books[9] = new Book("百年孤独", "马尔克斯", "文学", 78);size = 10;}public Book getBook(int index) {//得到序号为index的书籍return books[index];//不会越界,因为此时还没满}public void setBook(int index,Book book) {books[index] = book;}//将序号index处设置为××书public int getSize() {return size;//有效书籍数量}public void setSize(int size) {this.size = size;//设置有效书籍数量}
}

1.3Main类

 

package library;import library.user.NormalUser;
import library.user.User;
import library.user.Admin;
import java.util.Scanner;
public class Main {private static User login(){System.out.println("请输入您的姓名:");Scanner scanner =new Scanner(System.in);String name = scanner.next();System.out.println("请输入您的角色(1.普通用户2.管理员)");int role = scanner.nextInt();if (role==1){return new NormalUser(name);}else if(role==2){return new Admin(name);}else{System.out.println("输入的角色有误");return null;}}public static void main(String[] args) {//书记管理library.BookList booklist=new BookList();//管理员和普通用户让用户选择User user = login();//User user=new NormalUser(name)//User user=new Admin(name)//向上转型while(true){int choice = user.menu();//多态user.work(choice,booklist);//将选择的菜单与书籍列表传入,假如是查找,普通用户}}
}

2.Operation包

2.1AddOperation类 

package library.Operation;
import library.user.User;
import library.Book;
import library.BookList;import java.util.Scanner;public class AddOperation implements IOperation {@Overridepublic void work(User user,BookList bookList) {System.out.println("新增图书");Scanner scanner=new Scanner(System.in);System.out.println("请输入书名:");String name = scanner.next();System.out.println("请输入作者:");String author =scanner.next();System.out.println("请输入价格");double price = scanner.nextDouble();System.out.println("请输入类别");String type=scanner.next();Book book =new Book(name,author,type,price);int size=bookList.getSize();bookList.setBook(size,book);//传入book就相当于传入引用的空间bookList.setSize(size+1);//不能忘了修改sizeSystem.out.println("新增图书完成!");}
}

 2.2BorrowOperation类 

package library.Operation;import library.Book;
import library.BookList;
import library.user.User;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;public class BorrowOperation implements IOperation {@Overridepublic void work(User user,BookList bookList) {System.out.println("借书");Scanner scanner=new Scanner(System.in);System.out.println("请输入要借阅的图书编号:");int id= scanner.nextInt();if(id<0||id>=bookList.getSize()){System.out.println("输入错误");return;}Book book=bookList.getBook(id);//获取第id本书对象if(book.isBorrowed()){//先判断一下是否被借出System.out.println("该书已经被借出了");//如果真就被借出了return;}book.setBorrowed(true);book.setBorrowDate(LocalDate.now());book.setDueDate(LocalDate.now().plusDays(1)); // 两周后到期// 记录用户的借阅类型以用于推荐user.recordBorrowedType(book.getType());// 新增:将借书记录写入文件try (BufferedWriter writer = new BufferedWriter(new FileWriter(CheckOverdueOperation.OVERDUE_FILE, true))) {String timestamp = LocalDate.now().format(DateTimeFormatter.ISO_DATE);writer.write("=== 借书操作时间: " + timestamp + " ===");writer.newLine();writer.write("书名: " + book.getName()+ ", 借阅日期: " + book.getBorrowDate()+ ", 应归还日期: " + book.getDueDate());writer.newLine();writer.newLine(); // 空行分隔不同记录} catch (IOException e) {System.out.println("警告:借书记录保存失败,但借书操作已成功。错误信息: " + e.getMessage());}//book.setBorrowed(true);//没借出我就可以借了System.out.println("借书成功!");//增加代码System.out.println("应归还日期:" + book.getDueDate());}
}

 2.3CheckOverdueOperation类 

//package library.Operation;
//
//
//
//import library.Book;
//import library.BookList;
//import library.user.User;
//
//import java.time.LocalDate;//增加
//import java.util.Scanner;
//
//public class CheckOverdueOperation implements IOperation {
//	@Override
//	public void work(User user,BookList bookList) {
//		boolean a=false;
//		System.out.println("=== 逾期书籍检查 ===");
//		for (int i = 0; i < bookList.getSize(); i++) {
//			Book book = bookList.getBook(i);//获取每一本书
//			if (book.isBorrowed() && LocalDate.now().isAfter(book.getDueDate())) {//
//				//isAfter用来检测一个日期是否在另一个日期之后
//				a=true;
//				System.out.println("逾期书籍:" + book.getName() + " 应归还日期:" + book.getDueDate());
//			}
//		}
//		if(!a){
//			System.out.println("当前没有逾期未归还的书籍");
//		}
//	}
//}
package library.Operation;import library.Book;
import library.BookList;
import library.user.User;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;public class CheckOverdueOperation implements IOperation {public static final String OVERDUE_FILE = "overdue_books.txt"; // 保存逾期记录的文件@Overridepublic void work(User user, BookList bookList) {System.out.println("=== 逾期书籍检查 ===");boolean hasOverdue = false;try (BufferedWriter writer = new BufferedWriter(new FileWriter(OVERDUE_FILE, true))) { // true 表示追加模式// 写入检查时间String timestamp = LocalDate.now().format(DateTimeFormatter.ISO_DATE);writer.write("=== 检查时间: " + timestamp + " ===");writer.newLine();// 遍历书籍for (int i = 0; i < bookList.getSize(); i++) {Book book = bookList.getBook(i);if (book.isBorrowed() && LocalDate.now().isAfter(book.getDueDate())) {// 控制台输出System.out.println("逾期书籍:" + book.getName() + " 应归还日期:" + book.getDueDate());// 写入文件writer.write("书名: " + book.getName()+ ", 应归还日期: " + book.getDueDate());writer.newLine();hasOverdue = true;}}if (!hasOverdue) {System.out.println("当前没有逾期未归还的书籍");writer.write("无逾期书籍");writer.newLine();}writer.newLine(); // 空行分隔不同检查记录} catch (IOException e) {System.out.println("保存逾期记录失败: " + e.getMessage());}}
}

 2.4DelOperation类 

package library.Operation;import library.Book;
import library.BookList;import java.util.Scanner;
import library.user.User;
public class DelOperation implements IOperation {@Overridepublic void work(User user,BookList bookList) {System.out.println("删除书籍");Scanner scanner=new Scanner(System.in);System.out.println("请输入要删除书籍的序号:");int index=scanner.nextInt();if(index<0||index>=bookList.getSize()) {System.out.println("序号超出范围");return;}if(index == bookList.getSize()-1){bookList.setSize(bookList.getSize()-1);//如果是最后一本书,直接将有效元素设置为size-1即可}else{//如果删除中间元素,就可以把最后一个元素,复制到待删除元素的位置上,然后size-1即可Book lastBook = bookList.getBook(bookList.getSize()-1);//先获取到最后一本书bookList.setBook(index,lastBook);bookList.setSize(bookList.getSize()-1);}System.out.println("删除书籍完成!");}
}

 2.5ExitOperation类 

package library.Operation;import library.BookList;
import library.user.User;
public class ExitOperation implements IOperation {@Overridepublic void work(User user,BookList bookList) {System.out.println("goodbye!");System.exit(0);//结束程序的方法}
}

 2.6FindOperation类 

package library.Operation;import library.Book;
import library.BookList;
import library.user.User;
import java.util.Scanner;public class FindOperation implements IOperation {@Overridepublic void work(User user, BookList bookList) {System.out.println("查找操作");Scanner scanner = new Scanner(System.in);//新增代码System.out.println("请输入查找的书名(支持模糊匹配):");String keyword = scanner.next();boolean found = false;for (int i = 0; i < bookList.getSize(); i++) {Book book = bookList.getBook(i);// 使用 contains 实现模糊匹配if (book.getName().contains(keyword)) {System.out.println(book);found = true;}}if (!found) {System.out.println("未找到包含 \"" + keyword + "\" 的书籍");}System.out.println("查找完毕");}
}

 2.7 IOperation接口

package library.Operation;
import library.user.User;
import library.BookList;public interface IOperation {// 理论上是可行的,但是不加接口的话,无法保证所有的类都提供了work方法,也没法保证work方法的参数都是相同的。// 而加上后就能强制统一,方便后续的调用,否则如果大家提供的方法各不相同,就会显得很乱。//也可以使用抽象类,但是我这个接口我只想保存一些方法,并没有什么实例属性要继承的//并且不能多继承//而User中的类是抽象性,因为我们需要继承name的属性void work(User user,BookList bookList);//在每一个操作中都要
}

2.8 ListOperation类 

package library.Operation;
import library.user.User;
import library.Book;
import library.BookList;public class ListOperation implements IOperation {@Overridepublic void work(User user,BookList bookList) {System.out.println("查看书籍列表");for(int i=0;i<bookList.getSize();i++){Book book = bookList.getBook(i);//拿到第i本书System.out.println("["+i+"]"+book);//进入到BookList类中,调用toString方法}}
}

2.9 RecommendOperation类 

package library.Operation;//新建RecommendOperation.javaimport library.Book;
import library.BookList;
import library.user.User;public class RecommendOperation implements IOperation {@Overridepublic void work(User user, BookList bookList) {System.out.println("=== 根据您的喜好推荐 ===");String favoriteType = user.getFavoriteType();System.out.println("根据您的阅读历史,我们推荐以下" + favoriteType + "类书籍:");int count = 0;for (int i = 0; i < bookList.getSize(); i++) {Book book = bookList.getBook(i);if (book.getType().equals(favoriteType) && !book.isBorrowed()) {System.out.println("《" + book.getName() + "》" + " - " + book.getAuthor());count++;if (count >= 3) break; // 最多推荐3本}}if (count == 0) {System.out.println("暂时没有找到相关推荐,试试其他类型的书籍吧!");}}
}

2.10 ReturnOperation类 

package library.Operation;
import library.user.User;
import library.Book;
import library.BookList;import java.util.Scanner;public class ReturnOperation implements IOperation {@Overridepublic void work(User user,BookList bookList) {System.out.println("还书");Scanner scanner=new Scanner(System.in);System.out.println("请输入要归还的图书编号:");int id= scanner.nextInt();if(id<0||id>=bookList.getSize()){System.out.println("输入错误");return;}Book book=bookList.getBook(id);if(!book.isBorrowed()){//先判断一下是否被借出falseSystem.out.println("该书没借出,不能归还");//如果没被借出了,就不能换return;}book.setBorrowed(false);System.out.println("还书成功!");}
}

3.user包

3.1Admin

package library.user;import library.Operation.IOperation;
import library.Operation.*;import java.util.Scanner;public class Admin extends User{//private IOperation[] operations;//存放管理员的方法,这是什么类型呢,接口类型//写到父类即可public Admin(String name) {super(name);operations=new IOperation[]{new ExitOperation(),//0new ListOperation(),//1new FindOperation(),//2new AddOperation(),//3new DelOperation(),//4};}@Overridepublic int menu() {System.out.println("==============================");System.out.println("欢迎您,"+name+"!");System.out.println("1.查看书籍列表");System.out.println("2.按照名字查找图书");System.out.println("3.新增图书");System.out.println("4.删除图书");System.out.println("0.退出");System.out.println("===============================");System.out.println("请输入您的操作:");Scanner scanner=new Scanner(System.in);int choice = scanner.nextInt();return choice;}
}

3.2NormalUser

package library.user;import library.Operation.IOperation;
import library.Operation.*;import java.util.Scanner;public class NormalUser extends User {//private IOperation[] operations;public NormalUser(String name) {super(name);//对所要的方法进行初始化operations = new IOperation[]{//普通用户进行的操作new ExitOperation(),//这是一个数组,此处下标为0new ListOperation(),new FindOperation(),new BorrowOperation(),new ReturnOperation(),new CheckOverdueOperation(), // 新增逾期检查new RecommendOperation(), // 新增推荐功能};}@Overridepublic int menu() {//打印菜单System.out.println("==============================");System.out.println("欢迎你,"+name+"!");//查看书籍列表//查找图书System.out.println("1.查看书籍列表");System.out.println("2.按照名字查找图书");System.out.println("3.借阅图书");System.out.println("4.归还图书");System.out.println("5.逾期检查");//新增System.out.println("6.个性化推荐");//新增System.out.println("0.退出");System.out.println("===============================");System.out.println("请输入您的操作:");Scanner scanner=new Scanner(System.in);int choice = scanner.nextInt();return choice;}
}

3.3User 

package library.user;
import java.util.HashMap;
import library.BookList;
import library.Operation.IOperation;
import java.util.Map;
public abstract class User {//不同 的用户不同的操作protected String name;//各个子类都有的内容,直接放在父类中//protected子类可以直接获取到,不必再去用getter setterprotected IOperation[] operations;//当前这个类能进行那些操作,就往这个数组里添加对应的对象public User(String name){this.name=name;}public abstract int menu();//不知道父类的菜单(父类就没有菜单),我知道的只有管理员和用户的菜单// 所以使用abstract,子类再进行重写//为了避免父类被不小心创建出实例,所以要抽象(因为不能出现“父类菜单”)// 新增代码protected Map<String, Integer> borrowHistory = new HashMap<>(); // 新增:借阅类型统计// 新增:记录借阅类型public void recordBorrowedType(String type) {borrowHistory.put(type, borrowHistory.getOrDefault(type, 0) + 1);//使用put方法加入键值对,type存在返回对应的值,否则返回0//put的作用是向Map集合中添加键值对,或者更新已经存在的键值对{文学,0}}// 新增:获取最常借阅的类型public String getFavoriteType() {String favorite = "未知";int maxCount = 0;for (Map.Entry<String, Integer> entry : borrowHistory.entrySet()) {//entrySet用于返回一个包含Map中所有键值对的集合//Map.Entry用来表示一个键值对实体if (entry.getValue() > maxCount) {maxCount = entry.getValue();favorite = entry.getKey();}}return favorite;}public void work(int choice, BookList bookList){//3.进入到父类的work方法if(choice<0||choice>=operations.length){System.out.println("输入的选项非法");return;}operations[choice].work(this,bookList);//4.调用我选择的方法里面的work方法,就能用此方法对booklist进行操作了}
}

相关文章:

  • 基于zernike 拟合生成包裹训练数据-可自定义拟合的项数
  • MySQL数据库容灾设计案例与SQL实现
  • stm32week15
  • Linux之进程概念
  • 命令行解释器中shell、bash和zsh的区别
  • Linux中常见开发工具简单介绍
  • 微软向现实低头:悄悄延长Windows 10的Microsoft 365支持
  • Newton GPU 机器人仿真器入门教程(零)— NVIDIA、DeepMind、Disney 联合推出
  • k8s的flannel生产实战与常见问题排查
  • 设计模式简述(十八)享元模式
  • 游戏引擎学习第274天:基于弹簧的动态动画
  • 5.1.1 WPF中Command使用介绍
  • 2025第九届御网杯网络安全大赛线上赛 区域赛WP (MISC和Crypto)(详解-思路-脚本)
  • 力扣刷题——二分查找总结
  • 三、Hive DDL数据库操作
  • [工具]B站缓存工具箱 (By 郭逍遥)
  • 【LeetCode Hot100 | 每日刷题】排序数组
  • Python中,async和with结合使用,有什么好处?
  • Unity 红点系统
  • 06.three官方示例+编辑器+AI快速学习webgl_animation_skinning_additive_blending
  • 广东:十年后省级水网主骨架全面建成,与国家骨干网互联互通
  • 事关心脏健康安全,经导管植入式人工心脏瓣膜国家标准发布
  • 西王食品连亏三年:主业齐“崩”,研发人员多为专科生
  • 俄土外长通话讨论俄乌谈判问题
  • 听企业聊感受,《外企聊营商》5月13日起推出
  • 减重人生|走过节食弯路,她如何半年减60斤找回自信?