图书管理系统初级版用ArrayList内存存储,需校验用户输入、避免索引越界和类型异常,清缓冲区,非静态实例变量隔离状态,支持多条件搜索,健壮菜单循环防崩溃。

用 ArrayList + Scanner 实现核心增删查功能
图书管理系统初级版不需要数据库,用 ArrayList 存内存就够了。关键不是“怎么存”,而是“怎么让操作不崩”:用户输错类型、查不到书、删了不存在的 ID,这些地方必须加校验。
常见错误现象:InputMismatchException(Scanner 读 int 时输字母)、IndexOutOfBoundsException(删第 10 本书但只有 3 本)。
- 所有
scanner.nextInt()后紧跟scanner.nextLine()清缓冲区,否则下一次nextLine()会直接读到空行 - 删除/修改前先用
list.stream().anyMatch()查是否存在,别直接get(index) - 图书类
Book的id建议用Integer而非int,方便判null和后期扩展
public class Book {
private Integer id;
private String title;
private String author;
public Book(Integer id, String title, String author) {
this.id = id;
this.title = title;
this.author = author;
}
// getter/setter 省略
}
避免用静态变量管理数据导致的多实例混乱
新手常把 ArrayList 声明成 static,以为“全局好访问”。结果测试时创建多个 LibrarySystem 实例,数据互相污染——比如 A 实例删了一本书,B 实例里也消失了。
正确做法是把集合声明为实例变量,靠对象生命周期隔离状态:
立即学习“Java免费学习笔记(深入)”;
- 去掉
static修饰符,构造函数里初始化this.books = new ArrayList() - 主方法中只 new 一个实例:
new LibrarySystem().start();,别反复 new - 如果真要模拟“单例效果”,用
private static LibrarySystem instance+ 静态工厂方法,而不是把数据本身 static
搜索功能别只写“标题包含”,得支持多条件组合
单纯 book.getTitle().contains(keyword) 太弱。用户输入“Java 编程”时,应能同时匹配标题含“Java”且作者含“编程”的书(哪怕作者字段其实是“李编程”),而不是只搜一个字段。
实操建议:
- 搜索方法接收
String titleKeyword,String authorKeyword,Integer minId三个参数,允许部分为null - 用 Stream API 链式过滤:
books.stream().filter(b -> (titleKeyword == null || b.getTitle().contains(titleKeyword))).filter(...) - 注意大小写:用
toLowerCase().contains(...toLowerCase()),别让用户纠结“java”和“Java”
控制台交互容易卡死?用 do-while + 异常捕获兜底
菜单循环最常见崩溃点:用户输了个字母,程序抛异常后退出,连“按任意键继续”都没机会显示。
解决方式不是拼命 try-catch 每一行,而是把整个菜单逻辑包进一个健壮循环:
- 用
do { ... } while (!exitFlag),每次循环开头重置scanner状态 - 在循环内统一 catch
InputMismatchException和NumberFormatException,打印“输入无效,请重试”,然后continue - 选项 switch 里每个 case 结尾加
scanner.nextLine(),防止残留回车影响下一轮
真正难的不是写完功能,是让系统在用户各种乱输、中断、重复操作下依然稳住不崩——这比业务逻辑更体现初级项目的完成度。









