学生考勤记录系统需要完成学生信息存储、考勤状态登记、记录持久化保存和查询统计等核心功能,Java的集合框架可以高效管理内存中的临时考勤数据,配合文件操作就能实现数据的长期保存,两者结合可以搭建出轻量且实用的考勤系统。

系统核心数据结构设计
首先需要定义学生考勤记录的基础实体类,封装单条考勤的核心信息,方便后续在集合和文件之间流转数据。
// 学生考勤记录实体类
public class AttendanceRecord {
// 学生学号
private String studentId;
// 学生姓名
private String studentName;
// 考勤日期
private String attendanceDate;
// 考勤状态 1-出勤 2-迟到 3-缺勤 4-请假
private int attendanceStatus;
public AttendanceRecord(String studentId, String studentName, String attendanceDate, int attendanceStatus) {
this.studentId = studentId;
this.studentName = studentName;
this.attendanceDate = attendanceDate;
this.attendanceStatus = attendanceStatus;
}
// getter和setter方法
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getAttendanceDate() {
return attendanceDate;
}
public void setAttendanceDate(String attendanceDate) {
this.attendanceDate = attendanceDate;
}
public int getAttendanceStatus() {
return attendanceStatus;
}
public void setAttendanceStatus(int attendanceStatus) {
this.attendanceStatus = attendanceStatus;
}
// 转换为文件存储格式的字符串
public String toFileString() {
return studentId + "," + studentName + "," + attendanceDate + "," + attendanceStatus;
}
// 从文件字符串解析为对象
public static AttendanceRecord fromFileString(String fileLine) {
String[] parts = fileLine.split(",");
if (parts.length == 4) {
return new AttendanceRecord(parts[0], parts[1], parts[2], Integer.parseInt(parts[3]));
}
return null;
}
}
集合框架的选型与使用
内存中管理考勤记录时,需要根据操作场景选择合适的集合类型:
- ArrayList:适合存储所有考勤记录,支持按插入顺序遍历,方便批量展示和写入文件
- HashMap:适合按学号快速查询学生的所有考勤记录,键为学号,值为该学生的考勤记录列表
集合初始化与基础操作
在系统启动时,我们可以先定义两个核心集合容器:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AttendanceSystem {
// 存储所有考勤记录的列表
private List<AttendanceRecord> allRecords;
// 按学号分组存储考勤记录的映射
private Map<String, List<AttendanceRecord>> recordsByStudentId;
public AttendanceSystem() {
allRecords = new ArrayList<>();
recordsByStudentId = new HashMap<>();
}
// 添加考勤记录到集合
public void addAttendanceRecord(AttendanceRecord record) {
// 添加到总记录列表
allRecords.add(record);
// 按学号分组存储
String studentId = record.getStudentId();
if (!recordsByStudentId.containsKey(studentId)) {
recordsByStudentId.put(studentId, new ArrayList<>());
}
recordsByStudentId.get(studentId).add(record);
}
// 根据学号查询学生的所有考勤记录
public List<AttendanceRecord> getRecordsByStudentId(String studentId) {
return recordsByStudentId.getOrDefault(studentId, new ArrayList<>());
}
}
文件操作实现数据持久化
集合中的数据在程序关闭后会丢失,因此需要将考勤记录写入文件保存,程序启动时再从文件读取加载到集合中。
考勤记录写入文件
我们将考勤记录按行存储到文本文件中,每行对应一条记录,字段之间用逗号分隔:
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
public class FileUtil {
// 将考勤记录列表写入文件
public static void writeRecordsToFile(List<AttendanceRecord> records, String filePath) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
for (AttendanceRecord record : records) {
// 调用实体类的转换方法生成文件格式字符串
writer.write(record.toFileString());
writer.newLine();
}
System.out.println("考勤记录写入文件成功,共写入" + records.size() + "条记录");
} catch (IOException e) {
System.err.println("写入文件失败:" + e.getMessage());
}
}
}
从文件读取考勤记录加载到集合
程序启动时读取文件内容,解析为AttendanceRecord对象后添加到系统的集合中:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class FileUtil {
// 从文件读取考勤记录
public static List<AttendanceRecord> readRecordsFromFile(String filePath) {
List<AttendanceRecord> records = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
AttendanceRecord record = AttendanceRecord.fromFileString(line);
if (record != null) {
records.add(record);
}
}
System.out.println("从文件读取考勤记录成功,共读取" + records.size() + "条记录");
} catch (IOException e) {
System.err.println("读取文件失败:" + e.getMessage());
}
return records;
}
}
系统完整功能整合
将集合操作和文件操作整合,实现完整的考勤系统功能:
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
AttendanceSystem system = new AttendanceSystem();
Scanner scanner = new Scanner(System.in);
String filePath = "attendance_records.txt";
// 程序启动时从文件加载已有考勤记录
List<AttendanceRecord> loadedRecords = FileUtil.readRecordsFromFile(filePath);
for (AttendanceRecord record : loadedRecords) {
system.addAttendanceRecord(record);
}
// 模拟添加新考勤记录
System.out.println("请输入学生学号:");
String studentId = scanner.nextLine();
System.out.println("请输入学生姓名:");
String studentName = scanner.nextLine();
System.out.println("请输入考勤日期(格式:yyyy-MM-dd):");
String date = scanner.nextLine();
System.out.println("请输入考勤状态(1-出勤 2-迟到 3-缺勤 4-请假):");
int status = scanner.nextInt();
AttendanceRecord newRecord = new AttendanceRecord(studentId, studentName, date, status);
system.addAttendanceRecord(newRecord);
// 程序退出前将所有记录写入文件
FileUtil.writeRecordsToFile(system.getAllRecords(), filePath);
scanner.close();
}
}
注意事项
- 文件读写时要处理
IOException异常,避免程序因文件不存在或权限问题崩溃 - 如果考勤记录量较大,可以考虑使用缓冲流提升文件读写效率
- 集合操作时如果需要频繁按学号查询,优先使用
HashMap而不是遍历ArrayList,降低时间复杂度 - 文件存储的字段分隔符可以根据需求调整,若字段内容可能包含逗号,建议使用更复杂的分隔规则或转义处理