用 Java 实现控制台版图书管理系统:从需求到代码的完整实践

用 Java 实现控制台版图书管理系统:从需求到代码的完整实践

我不是广告

个人主页-爱因斯晨

文章专栏-JAVA学习

好久不见~最近变了很多,也在忙。也有点儿小体会吧,最近遇到了很多事儿,我也想了很多。我个人的想法还是:不能给自己的以后留下任何污点,因为路还很长,我这才刚开始。要坚守自己的底线吧!“苟非吾之所有,虽一毫而莫取”
最后,衷心祝大家,身心健康,注意好身体!

在这里插入图片描述

> 不知道大家喜欢听歌嘛?最近发现一个可以白嫖会员的东西,苹果音乐可以白嫖会员(新用户两个月,老用户一个月),苹果安卓都能用,领取之后记得关闭自动续费哦~曲库还是很多的,大家可以点击链接领取。领取链接绝对免费!绝对白嫖!

作为一名 Java 开发者,我们常常忙于框架和中间件的使用,却容易忽略基础语法的实战价值。今天,我将带大家从零开始实现一个控制台版图书管理系统,这个项目虽然简单,却涵盖了 Java 核心基础的大部分知识点,非常适合初学者巩固基础,也能让资深开发者重温 Java 设计的初心。

项目需求分析

在开始编码之前,我们需要明确这个图书管理系统应该具备哪些核心功能。一个最简化的图书管理系统应当包含:

  • 图书信息的管理(图书包含 ID、书名、作者、出版社、是否可借等属性)
  • 基本的 CRUD 操作(添加、查询、修改、删除图书)
  • 借阅和归还功能
  • 简单的控制台交互界面

这些功能虽然基础,但足以覆盖 Java 基础中的类与对象、集合框架、控制流、异常处理等核心知识点。

系统设计思路

对于这样一个小型项目,我们采用简单的三层结构设计:

  1. 实体层(Model):定义图书对象的属性和行为
  2. 业务逻辑层(Service):处理核心业务逻辑
  3. 视图层(View):负责控制台交互

这种分层思想即使在大型项目中也是核心设计原则,从小项目开始培养这种思维非常重要。

代码实现

1. 实体类设计

首先我们创建 Book 类,封装图书的基本信息和相关方法:

publicclassBook{privateString id;// 图书唯一标识privateString title;// 书名privateString author;// 作者privateString publisher;// 出版社privateboolean isBorrowed;// 是否被借出// 构造方法publicBook(String id,String title,String author,String publisher){this.id = id;this.title = title;this.author = author;this.publisher = publisher;this.isBorrowed =false;// 默认可借}// getter和setter方法publicStringgetId(){return id;}publicStringgetTitle(){return title;}publicvoidsetTitle(String title){this.title = title;}publicStringgetAuthor(){return author;}publicvoidsetAuthor(String author){this.author = author;}publicStringgetPublisher(){return publisher;}publicvoidsetPublisher(String publisher){this.publisher = publisher;}publicbooleanisBorrowed(){return isBorrowed;}publicvoidsetBorrowed(boolean borrowed){ isBorrowed = borrowed;}// 重写toString方法,方便打印图书信息@OverridepublicStringtoString(){returnString.format("ID: %s\n书名: %s\n作者: %s\n出版社: %s\n状态: %s", id, title, author, publisher, isBorrowed ?"已借出":"可借阅");}}

这个类体现了 Java 的封装特性,通过 private 修饰属性,提供 public 的 getter 和 setter 方法来访问和修改属性,同时重写了 toString () 方法方便输出图书信息。

2. 业务逻辑层实现

接下来实现 BookService 类,处理图书管理的核心业务逻辑:

importjava.util.ArrayList;importjava.util.List;importjava.util.Scanner;publicclassBookService{// 使用ArrayList存储图书,模拟数据库privateList<Book> books =newArrayList<>();privateScanner scanner =newScanner(System.in);// 添加图书publicvoidaddBook(){System.out.println("===== 添加新图书 =====");System.out.print("请输入图书ID: ");String id = scanner.nextLine();// 检查ID是否已存在if(findBookById(id)!=null){System.out.println("错误:该ID已存在!");return;}System.out.print("请输入书名: ");String title = scanner.nextLine();System.out.print("请输入作者: ");String author = scanner.nextLine();System.out.print("请输入出版社: ");String publisher = scanner.nextLine();// 创建图书对象并添加到集合Book newBook =newBook(id, title, author, publisher); books.add(newBook);System.out.println("图书添加成功!");}// 查找图书(按ID)publicBookfindBookById(String id){for(Book book : books){if(book.getId().equals(id)){return book;}}returnnull;}// 查找图书(按书名)publicList<Book>findBooksByTitle(String title){List<Book> result =newArrayList<>();for(Book book : books){if(book.getTitle().contains(title)){ result.add(book);}}return result;}// 显示所有图书publicvoidshowAllBooks(){System.out.println("===== 所有图书 =====");if(books.isEmpty()){System.out.println("暂无图书信息");return;}for(Book book : books){System.out.println("-------------------");System.out.println(book);}System.out.println("-------------------");}// 更新图书信息publicvoidupdateBook(){System.out.println("===== 修改图书信息 =====");System.out.print("请输入要修改的图书ID: ");String id = scanner.nextLine();Book book =findBookById(id);if(book ==null){System.out.println("未找到该图书!");return;}System.out.println("当前图书信息:");System.out.println(book);System.out.print("请输入新书名(不修改按回车): ");String title = scanner.nextLine();if(!title.isEmpty()){ book.setTitle(title);}System.out.print("请输入新作者(不修改按回车): ");String author = scanner.nextLine();if(!author.isEmpty()){ book.setAuthor(author);}System.out.print("请输入新出版社(不修改按回车): ");String publisher = scanner.nextLine();if(!publisher.isEmpty()){ book.setPublisher(publisher);}System.out.println("图书信息修改成功!");}// 删除图书publicvoiddeleteBook(){System.out.println("===== 删除图书 =====");System.out.print("请输入要删除的图书ID: ");String id = scanner.nextLine();Book book =findBookById(id);if(book ==null){System.out.println("未找到该图书!");return;}// 检查图书是否已借出if(book.isBorrowed()){System.out.println("无法删除:该图书已被借出!");return;} books.remove(book);System.out.println("图书删除成功!");}// 借阅图书publicvoidborrowBook(){System.out.println("===== 借阅图书 =====");System.out.print("请输入要借阅的图书ID: ");String id = scanner.nextLine();Book book =findBookById(id);if(book ==null){System.out.println("未找到该图书!");return;}if(book.isBorrowed()){System.out.println("抱歉,该图书已被借出!");}else{ book.setBorrowed(true);System.out.println("借阅成功!请按时归还。");}}// 归还图书publicvoidreturnBook(){System.out.println("===== 归还图书 =====");System.out.print("请输入要归还的图书ID: ");String id = scanner.nextLine();Book book =findBookById(id);if(book ==null){System.out.println("未找到该图书!");return;}if(!book.isBorrowed()){System.out.println("错误:该图书未被借出!");}else{ book.setBorrowed(false);System.out.println("归还成功!感谢使用。");}}// 搜索图书publicvoidsearchBooks(){System.out.println("===== 搜索图书 =====");System.out.print("请输入书名关键词: ");String keyword = scanner.nextLine();List<Book> results =findBooksByTitle(keyword);if(results.isEmpty()){System.out.println("未找到匹配的图书!");return;}System.out.println("找到"+ results.size()+"本匹配的图书:");for(Book book : results){System.out.println("-------------------");System.out.println(book);}System.out.println("-------------------");}}

在这个类中,我们使用了 ArrayList来存储图书对象,模拟了数据库的功能。每个方法对应一个具体的业务操作,包含了参数校验和业务逻辑处理。

3. 视图层实现

最后实现主程序类,负责控制台交互:

importjava.util.Scanner;publicclassBookManagementSystem{privatestaticBookService bookService =newBookService();privatestaticScanner scanner =newScanner(System.in);publicstaticvoidmain(String[] args){System.out.println("===== 欢迎使用图书管理系统 =====");showMenu();while(true){System.out.print("\n请输入操作编号: ");String choice;try{ choice = scanner.nextLine().trim();handleChoice(choice);}catch(Exception e){System.out.println("操作出错:"+ e.getMessage());System.out.println("请重新输入!");}}}// 显示菜单privatestaticvoidshowMenu(){System.out.println("\n操作菜单:");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("7. 搜索图书");System.out.println("0. 退出系统");}// 处理用户选择privatestaticvoidhandleChoice(String choice){switch(choice){case"1": bookService.addBook();break;case"2": bookService.showAllBooks();break;case"3": bookService.updateBook();break;case"4": bookService.deleteBook();break;case"5": bookService.borrowBook();break;case"6": bookService.returnBook();break;case"7": bookService.searchBooks();break;case"0":System.out.println("感谢使用,再见!");System.exit(0);break;default:System.out.println("无效的操作编号,请重新输入!");}showMenu();}}

这个类实现了控制台菜单的展示和用户输入的处理,通过调用 BookService 的方法来完成具体的业务操作。

代码解析与知识点总结

这个简单的图书管理系统虽然代码量不大,但包含了 Java 基础的多个重要知识点:

  1. 面向对象编程:通过 Book 类封装图书属性和行为,体现了封装性;系统分层设计体现了模块化思想。
  2. 集合框架:使用ArrayList存储图书对象,展示了 Java 集合的基本用法,相比数组更加灵活。
  3. 控制流:大量使用 if-else 条件判断和 switch 选择结构,以及 for 循环遍历集合。
  4. 异常处理:在主程序中使用 try-catch 块捕获可能的异常,保证程序的健壮性。
  5. IO 操作:通过 Scanner 类实现控制台输入输出,是 Java IO 的基础应用。
  6. 方法设计:将不同功能封装成独立方法,提高代码的可读性和复用性。

功能扩展思路

这个基础版本的图书管理系统可以从多个方向进行扩展,使其更接近实际应用:

  1. 数据持久化:目前数据存储在内存中,程序退出后数据会丢失。可以添加文件 IO 操作,将图书信息保存到本地文件。
  2. 用户管理:增加用户登录功能,区分管理员和普通用户权限。
  3. 借阅记录:添加借阅记录功能,记录谁在什么时间借阅了什么图书。
  4. 更完善的查询:支持按作者、出版社等多条件组合查询。
  5. 图书分类:为图书添加分类属性,支持按分类管理图书。

项目收获与反思

通过实现这个图书管理系统,我们可以深刻体会到:

  1. 基础的重要性:复杂的系统都是由简单的模块构成的,扎实的基础是构建复杂系统的前提。
  2. 模块化思维:将功能拆分成独立的模块和方法,不仅便于开发,也利于后期维护和扩展。
  3. 用户体验:即使是控制台程序,也需要考虑用户交互的友好性,清晰的提示和简洁的操作流程很重要。
  4. 异常处理:在实际开发中,异常处理是保证程序稳定性的关键,需要仔细考虑各种可能的异常情况。

结语

这个控制台版图书管理系统虽然简单,但完整地实现了一个小型应用的开发流程,从需求分析到设计,再到编码实现。对于 Java 初学者来说,这是一个非常好的练手项目,能够帮助巩固基础知识,培养编程思维。

对于有经验的开发者,这样的基础项目也能让我们回归 Java 的本质,思考如何用最简洁的代码实现需求,而不是过度依赖框架和工具。

希望这个项目能给大家带来启发,也欢迎大家在此基础上进行扩展和优化,探索更多 Java 编程的乐趣。

Read more

JavaScript:编程世界中的“语盲”现象

JavaScript:编程世界中的“语盲”现象

前言 JavaScript 是现代前端开发中必不可少的编程语言,以其强大的功能、丰富的API库以及跨平台特性深受开发者喜爱。然而,在它的广泛应用背后,JavaScript 也被认为是“最被误解的语言”。这种误解源于其复杂性和多面性,使得许多开发者在使用时感到困惑和压力。   语法复杂性 JavaScript 的语法与传统编程语言如 C 或 Java 明显不同,这让初学者感到难以适应。尽管 JavaScript 允许显式和隐式的变量类型转换,但在实际应用中,这种特性有时会导致代码混淆。例如,字符串操作符 + 在 JavaScript 中既可以用于数字相加,也可以用于连接字符串,这使得理解代码变得具有挑战性。 此外,JavaScript 的语法虽然与 Java 有一定的相似之处,但其细节上存在显著差异。例如,数组的增量操作使用 [ ] 符号,而对象的属性使用 . 或 [] 符号进行访问。这些微小的区别常常让开发者感到困惑,尤其是在处理变量和数据类型时。 动态类型系统 JavaScript 是一种基于弱类型的语言,这意味着它允许显式和隐式的变量类型转换。

By Ne0inhk
从反射到方法句柄:深入探索Java动态编程的终极解决方案

从反射到方法句柄:深入探索Java动态编程的终极解决方案

🌟 你好,我是 励志成为糕手 ! 🌌 在代码的宇宙中,我是那个追逐优雅与性能的星际旅人。 ✨ 每一行代码都是我种下的星光,在逻辑的土壤里生长成璀璨的银河; 🛠️ 每一个算法都是我绘制的星图,指引着数据流动的最短路径; 🔍 每一次调试都是星际对话,用耐心和智慧解开宇宙的谜题。 🚀 准备好开始我们的星际编码之旅了吗? 目录 摘要  一、Java反射机制基础 1.1 什么是反射? 1.2 Java反射核心类关系图 1.3 反射的核心原理 二、反射核心操作详解 2.1 获取Class对象的三种方式 2.2 动态创建对象实例 2.3 动态调用方法 2.4 动态操作字段 三、反射的典型应用场景 3.1 框架开发(Spring IOC容器) 3.2 动态代理(JDK

By Ne0inhk
【YF技术周报 Vol.01】OpenAI 国会指控 DeepSeek,字节发布 Seedance 2.0,Java 26 预览版来了

【YF技术周报 Vol.01】OpenAI 国会指控 DeepSeek,字节发布 Seedance 2.0,Java 26 预览版来了

🍃 予枫:个人主页 📚 个人专栏: 《Java 从入门到起飞》《读研码农的干货日常》 💻 Debug 这个世界,Return 更好的自己! 文章目录 * 🚨 1. OpenAI 向美国国会提交备忘录:指控 DeepSeek “非法蒸馏” * 🎬 2. 字节跳动发布 Seedance 2.0:对标 Sora 的视频生成模型 * 🛑 3. OpenAI 正式下线 GPT-4o,全面转向 GPT-5 * ☕ 4. Azul 发布《2026 Java 现状报告》:AI 开发中的 Java 渗透率攀升 * 💡 YF 的深度思考:护城河与工具链 👋 卷首语 大家好,我是予枫。 这是 《YF 技术周报》

By Ne0inhk
双非 Java 后端首次实习 | 个人经验分享总结

双非 Java 后端首次实习 | 个人经验分享总结

摘要:实习期间参与企业后台项目开发,熟悉企业开发流程与代码规范。 实习核心流程(结合实际经历) 由于自己进入的是一个小公司实习,当时项目刚好启动,参与了较多基础模块的开发。 一、基础准备与环境搭建阶段(入职 1-3 天) 1. 公司基础配置:进入公司飞书、拥有个人邮箱等基础办公权限 2. 代码拉取与环境搭建: * 学习并使用 git/svn 等版本管理工具 clone 项目代码(公司使用的是阿里云云效) * 配置项目所需配置文件,搭建后端 + 前端开发环境(后端需兼顾前端环境) * 解决环境依赖问题,确保项目能正常跑起来(熟悉配置文件与环境) * 熟悉开发工具的使用,避免因操作问题浪费时间(mentor 教了debug技巧,快捷键) 二、项目熟悉阶段(入职 1-2 周) 这个阶段任务主要是熟悉环境,熟练使用通用封装 / 工具类,自己在熟悉项目的时候,寻找少量项目bug,提交问题给 mentor

By Ne0inhk