初学者应先用ArrayList和Scanner实现图书借阅核心流程,定义Book(含isbn、title、author、isBorrowed)和BorrowRecord(含bookIsbn、borrowerName、borrowDate)两个类,用for循环处理借书逻辑,注意Scanner.nextLine()前需调用scanner.nextLine()清除换行符,并用文本文件保存数据。

Java初学者做图书借阅系统,别一上来就画UML、搞Spring Boot、连MySQL——先用ArrayList和Scanner把核心流程跑通,否则连“书被借走后还能不能借”这种逻辑都容易绕晕。
用Book和BorrowRecord类建模,别急着加继承和接口
初学者最容易堆砌抽象:一想“书”就建Item父类,再搞Magazine子类……实际第一版只要两个干净的类:
-
Book:含isbn(String)、title、author、isBorrowed(boolean)字段,配toString()方便调试 -
BorrowRecord:只存bookIsbn、borrowerName、borrowDate(用LocalDate.now()即可),不用建时间范围或归还状态
这样写,main里几行就能打印出“张三借了《算法导论》”,而不是卡在泛型擦除或空指针上。
借书逻辑用for遍历+break,别碰Stream API
查书是否存在、是否已借出,用传统循环更直观。用Stream.filter().findFirst()看似简洁,但初学者常写错Optional判空,导致NoSuchElementException崩溃。
立即学习“Java免费学习笔记(深入)”;
for (Book book : bookList) {
if (book.getIsbn().equals(isbn) && !book.isBorrowed()) {
book.setBorrowed(true);
records.add(new BorrowRecord(isbn, borrower));
System.out.println("借阅成功");
break;
}
}
注意三点:
- 必须用
.equals()比ISBN,不是== - 找到就
break,避免重复借同一本书 - 没找到要单独打印“未找到该书”或“已被借出”,否则用户以为程序卡了
用Scanner.nextLine()读字符串,小心nextInt()留下的换行符
菜单选1借书、2还书、0退出,用nextInt()读选项没问题;但紧接着用nextLine()读书名或姓名时,会直接拿到空字符串——因为nextInt()不吞掉回车。
解决方法只有这一种:
int choice = scanner.nextInt();
scanner.nextLine(); // 吃掉换行符
System.out.print("请输入书名:");
String title = scanner.nextLine();
漏掉这行,所有输入都会错位,且错误不报异常,极难排查。
保存数据?先用PrintWriter写文本文件,别碰JSON或数据库
退出前把bookList和records写进books.txt和records.txt,每行一条记录,字段用|分隔:
978-7-302-18425-0|算法导论|Thomas H. Cormen|true 978-7-302-53688-8|深入理解计算机系统|Randall Bryant|false
下次启动时用Files.readAllLines()读回来,split("\\|")拆字段。这样比硬啃JDBC驱动或H2内存库实在得多。
真正容易被忽略的,是LocalDate序列化——它默认转成2024-05-20字符串,读的时候用LocalDate.parse(line.split("\\|")[2])就行,别自己解析年月日。










