一、实验目的
1、掌握集合的创建和操作方法。
2、理解泛型的作用,并掌握类型在集合中的应用。
二、实验环境
Windows,IDEA。
三、实验内容
图书馆中的每本书都有一个ID号和书名,每本书的ID号是唯一的。data.txt中为各读者的借阅记录,每条记录包括读者的姓名和借阅的图书ID。编写一个Java程序,完成以下功能:
1、定义借阅记录类BorrowRecord,它包含两个属性:readerName 和 bookId,并实现 Comparable 接口用于排序。
2、统计并输出每位读者借阅的所有书籍id。
3、统计并输出每本书的所有借阅者姓名。
4、按借阅者所借阅图书的数量从大到小排序输出。
输出结果参照下面的格式显示:
每位读者借阅的书籍: 李四 借阅的书籍ID: [1005, 1004, 1002, 1001] …… 每本书的借阅者: 书籍ID 1005 的借阅者: [李四, 王五] ……] 每位读者借阅的书籍数量(从大到小排序): 李四 - 9本 …… |
五.源代码
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
// 借阅记录类
class BorrowRecord implements Comparable<BorrowRecord> {
private String readerName; // 读者姓名
private int bookId; // 书籍ID
// 构造方法
public BorrowRecord(String readerName, int bookId) {
this.readerName = readerName;
this.bookId = bookId;
}
// 获取读者姓名
public String getReaderName() {
return readerName;
}
// 获取书籍ID
public int getBookId() {
return bookId;
}
// 实现 Comparable 接口的 compareTo 方法,用于排序
@Override
public int compareTo(BorrowRecord other) {
return Integer.compare(this.bookId, other.bookId);
}
}
// 主程序类
public class dome1 {
public static void main(String[] args) {
// 读取借阅记录文件,获取借阅记录列表
List<BorrowRecord> borrowRecords = readBorrowRecordsFromFile("D:\\data.txt");
// 统计每位读者借阅的书籍
Map<String, List<Integer>> readerBooks = new HashMap<>();
for (BorrowRecord record : borrowRecords) {
String reader = record.getReaderName();
int bookId = record.getBookId();
// 如果读者名不存在于 Map 中,则创建新的列表;否则,将书籍ID添加到已有列表中
readerBooks.computeIfAbsent(reader, k -> new ArrayList<>()).add(bookId);
}
// 输出每位读者借阅的书籍
for (Map.Entry<String, List<Integer>> entry : readerBooks.entrySet()) {
System.out.println(entry.getKey() + " 借阅的书籍ID: " + entry.getValue());
}
// 统计每本书的借阅者
Map<Integer, List<String>> bookReaders = new HashMap<>();
for (BorrowRecord record : borrowRecords) {
int bookId = record.getBookId();
String reader = record.getReaderName();
// 如果书籍ID不存在于 Map 中,则创建新的列表;否则,将读者名添加到已有列表中
bookReaders.computeIfAbsent(bookId, k -> new ArrayList<>()).add(reader);
}
// 输出每本书的借阅者
for (Map.Entry<Integer, List<String>> entry : bookReaders.entrySet()) {
System.out.println("书籍ID " + entry.getKey() + " 的借阅者: " + entry.getValue());
}
// 统计每位读者借阅的书籍数量(从大到小排序)
Map<String, Integer> readerBookCount = new HashMap<>();
for (Map.Entry<String, List<Integer>> entry : readerBooks.entrySet()) {
readerBookCount.put(entry.getKey(), entry.getValue().size());
}
// 排序并输出每位读者借阅的书籍数量
List<Map.Entry<String, Integer>> sortedList = new ArrayList<>(readerBookCount.entrySet());
sortedList.sort((e1, e2) -> Integer.compare(e2.getValue(), e1.getValue()));
for (Map.Entry<String, Integer> entry : sortedList) {
System.out.println(entry.getKey() + " - " + entry.getValue() + "本");
}
}
// 从文件中读取借阅记录并返回记录列表
private static List<BorrowRecord> readBorrowRecordsFromFile(String filename) {
List<BorrowRecord> records = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = br.readLine()) != null) {
String[] parts = line.split(" ");
if (parts.length == 2) {
String readerName = parts[0];
int bookId = Integer.parseInt(parts[1]);
records.add(new BorrowRecord(readerName, bookId));
}
}
} catch (IOException | NumberFormatException e) {
e.printStackTrace();
}
return records;
}
}
六.程序运行结果截图
七、小结
知识掌握情况;存在的问题,如何解决
异常处理: 在 readBorrowRecordsFromFile 方法中,如果文件读取或转换数字的过程中发生异常,程序会打印堆栈跟踪并继续执行。你可能希望更加友好地处理这些异常,例如打印错误消息并终止程序,或者提供用户有关错误的更详细的信息。
文件路径: 确保 data.txt 文件在你的项目根目录下,或者提供文件的绝对路径。否则,程序可能无法找到文件。
增加注释: 为了提高代码的可读性,你可以添加更多注释,解释程序中各个部分的功能和逻辑
更灵活的文件名: 将文件名硬编码在代码中可能不太灵活。你可以将文件名作为程序参数传递给 main 方法,这样用户可以在运行时指定文件名。