系统特点
- 面向对象设计:使用
Student类来封装学生数据,结构清晰。 - 数据持久化:使用
FileInputStream和ObjectInputStream将学生对象列表保存到students.dat文件中,实现了程序关闭后数据不丢失。 - 功能完整:提供了增、删、改、查、显示等核心功能。
- 用户友好:提供清晰的菜单和操作提示。
- 代码注释:代码中包含详细的注释,方便理解和学习。
项目结构
这个项目非常简单,只需要两个 Java 文件:

StudentManagementSystem/
├── Student.java // 学生类(数据模型)
└── StudentManagementSystem.java // 主程序类(包含所有逻辑和菜单)
Student.java (学生实体类)
这个类定义了一个学生的属性,并实现了 Serializable 接口,以便对象可以被序列化后写入文件。
import java.io.Serializable;
/**
* 学生类,用于封装学生信息
* 实现 Serializable 接口,以便对象可以被序列化
*/
public class Student implements Serializable {
private static final long serialVersionUID = 1L; // 序列化版本号
private String id; // 学号
private String name; // 姓名
private int age; // 年龄
private String gender; // 性别
private String major; // 专业
// 构造方法
public Student(String id, String name, int age, String gender, String major) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.major = major;
}
// Getter 和 Setter 方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
// 重写 toString() 方法,方便打印学生信息
@Override
public String toString() {
return "学号: " + id +
", 姓名: " + name +
", 年龄: " + age +
", 性别: " + gender +
", 专业: " + major;
}
}
StudentManagementSystem.java (主程序类)
这是系统的核心,包含了主菜单、各个功能方法的实现以及文件读写逻辑。
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
/**
* 学生信息管理系统主程序
*/
public class StudentManagementSystem {
// 使用 List 来存储所有学生对象
private static List<Student> studentList = new ArrayList<>();
// 定义文件名,用于持久化存储数据
private static final String FILE_NAME = "students.dat";
// 使用 Scanner 来接收用户输入
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
// 程序启动时,首先从文件加载数据
loadData();
// 显示主菜单
while (true) {
showMenu();
int choice = getChoice();
switch (choice) {
case 1:
addStudent();
break;
case 2:
deleteStudent();
break;
case 3:
updateStudent();
break;
case 4:
findStudent();
break;
case 5:
displayAllStudents();
break;
case 0:
// 退出程序前,保存数据到文件
saveData();
System.out.println("感谢使用,再见!");
scanner.close(); // 关闭 Scanner
System.exit(0); // 退出程序
default:
System.out.println("无效的输入,请重新输入!");
}
}
}
/**
* 显示系统主菜单
*/
private static void showMenu() {
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(" 0. 退出系统");
System.out.println("=====================================");
System.out.print("请选择操作: ");
}
/**
* 获取用户输入的选项
* @return 用户选择的数字
*/
private static int getChoice() {
try {
return Integer.parseInt(scanner.nextLine());
} catch (NumberFormatException e) {
return -1; // 如果输入的不是数字,返回-1
}
}
/**
* 添加学生
*/
private static void addStudent() {
System.out.println("--- 添加学生信息 ---");
System.out.print("请输入学号: ");
String id = scanner.nextLine();
// 检查学号是否已存在
if (studentList.stream().anyMatch(s -> s.getId().equals(id))) {
System.out.println("错误:该学号已存在!");
return;
}
System.out.print("请输入姓名: ");
String name = scanner.nextLine();
System.out.print("请输入年龄: ");
int age = Integer.parseInt(scanner.nextLine());
System.out.print("请输入性别: ");
String gender = scanner.nextLine();
System.out.print("请输入专业: ");
String major = scanner.nextLine();
Student student = new Student(id, name, age, gender, major);
studentList.add(student);
System.out.println("学生信息添加成功!");
}
/**
* 删除学生
*/
private static void deleteStudent() {
System.out.println("--- 删除学生信息 ---");
System.out.print("请输入要删除学生的学号: ");
String id = scanner.nextLine();
// 使用 Stream API 查找并删除
boolean removed = studentList.removeIf(s -> s.getId().equals(id));
if (removed) {
System.out.println("学生信息删除成功!");
} else {
System.out.println("未找到该学号的学生,删除失败!");
}
}
/**
* 修改学生信息
*/
private static void updateStudent() {
System.out.println("--- 修改学生信息 ---");
System.out.print("请输入要修改学生的学号: ");
String id = scanner.nextLine();
// 使用 Stream API 查找学生
Student studentToUpdate = studentList.stream()
.filter(s -> s.getId().equals(id))
.findFirst()
.orElse(null);
if (studentToUpdate == null) {
System.out.println("未找到该学号的学生,修改失败!");
return;
}
System.out.println("已找到学生: " + studentToUpdate);
System.out.println("请输入新的信息 (直接回车则保持原值):");
System.out.print("姓名 (" + studentToUpdate.getName() + "): ");
String name = scanner.nextLine();
if (!name.isEmpty()) studentToUpdate.setName(name);
System.out.print("年龄 (" + studentToUpdate.getAge() + "): ");
String ageStr = scanner.nextLine();
if (!ageStr.isEmpty()) studentToUpdate.setAge(Integer.parseInt(ageStr));
System.out.print("性别 (" + studentToUpdate.getGender() + "): ");
String gender = scanner.nextLine();
if (!gender.isEmpty()) studentToUpdate.setGender(gender);
System.out.print("专业 (" + studentToUpdate.getMajor() + "): ");
String major = scanner.nextLine();
if (!major.isEmpty()) studentToUpdate.setMajor(major);
System.out.println("学生信息修改成功!");
}
/**
* 查询学生信息
*/
private static void findStudent() {
System.out.println("--- 查询学生信息 ---");
System.out.print("请输入要查询的学号或姓名: ");
String keyword = scanner.nextLine();
// 使用 Stream API 进行模糊查询
List<Student> foundStudents = studentList.stream()
.filter(s -> s.getId().contains(keyword) || s.getName().contains(keyword))
.collect(Collectors.toList());
if (foundStudents.isEmpty()) {
System.out.println("未找到匹配的学生信息。");
} else {
System.out.println("--- 查询结果 ---");
foundStudents.forEach(System.out::println);
}
}
/**
* 显示所有学生信息
*/
private static void displayAllStudents() {
System.out.println("--- 所有学生信息 ---");
if (studentList.isEmpty()) {
System.out.println("当前没有任何学生信息。");
} else {
studentList.forEach(System.out::println);
}
}
/**
* 从文件加载数据
*/
private static void loadData() {
File file = new File(FILE_NAME);
if (file.exists()) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME))) {
studentList = (List<Student>) ois.readObject();
System.out.println("数据加载成功,共 " + studentList.size() + " 条学生记录。");
} catch (IOException | ClassNotFoundException e) {
System.out.println("数据加载失败,将创建一个新的数据文件。");
studentList = new ArrayList<>(); // 如果加载失败,初始化一个空列表
}
} else {
System.out.println("未找到数据文件,将创建一个新的数据文件。");
}
}
/**
* 保存数据到文件
*/
private static void saveData() {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME))) {
oos.writeObject(studentList);
System.out.println("数据已成功保存到文件。");
} catch (IOException e) {
System.out.println("数据保存失败!");
e.printStackTrace();
}
}
}
如何运行
-
保存文件:将上面的两个代码块分别保存为
Student.java和StudentManagementSystem.java文件,并确保它们在同一个目录下。 -
编译:打开命令行(Windows 的 CMD 或 PowerShell,macOS/Linux 的 Terminal),进入到这两个文件所在的目录,然后执行编译命令:
(图片来源网络,侵删)javac Student.java StudentManagementSystem.java
如果没有错误,会生成
Student.class和StudentManagementSystem.class两个文件。 -
运行:运行主程序类:
java StudentManagementSystem
运行示例
========== 学生信息管理系统 ==========
1. 添加学生信息
2. 删除学生信息
3. 修改学生信息
4. 查询学生信息
5. 显示所有学生信息
0. 退出系统
=====================================
请选择操作: 1
--- 添加学生信息 ---
请输入学号: 2025001
请输入姓名: 张三
请输入年龄: 20
请输入性别: 男
请输入专业: 计算机科学
学生信息添加成功!
========== 学生信息管理系统 ==========
1. 添加学生信息
2. 删除学生信息
3. 修改学生信息
4. 查询学生信息
5. 显示所有学生信息
0. 退出系统
=====================================
请选择操作: 1
--- 添加学生信息 ---
请输入学号: 2025002
请输入姓名: 李四
请输入年龄: 21
请输入性别: 女
请输入专业: 软件工程
学生信息添加成功!
========== 学生信息管理系统 ==========
1. 添加学生信息
2. 删除学生信息
3. 修改学生信息
4. 查询学生信息
5. 显示所有学生信息
0. 退出系统
=====================================
请选择操作: 5
--- 所有学生信息 ---
学号: 2025001, 姓名: 张三, 年龄: 20, 性别: 男, 专业: 计算机科学
学号: 2025002, 姓名: 李四, 年龄: 21, 性别: 女, 专业: 软件工程
========== 学生信息管理系统 ==========
1. 添加学生信息
2. 删除学生信息
3. 修改学生信息
4. 查询学生信息
5. 显示所有学生信息
0. 退出系统
=====================================
请选择操作: 4
--- 查询学生信息 ---
请输入要查询的学号或姓名: 张
--- 查询结果 ---
学号: 2025001, 姓名: 张三, 年龄: 20, 性别: 男, 专业: 计算机科学
========== 学生信息管理系统 ==========
1. 添加学生信息
2. 删除学生信息
3. 修改学生信息
4. 查询学生信息
5. 显示所有学生信息
0. 退出系统
=====================================
请选择操作: 0
数据已成功保存到文件。
感谢使用,再见!
当你再次运行程序时,它会提示“数据加载成功”,并显示之前保存的学生信息。
扩展思路
这个版本是一个基础的控制台应用,如果你想进一步学习和改进,可以考虑以下方向:

- 图形用户界面:使用 Java Swing 或 JavaFX 来开发一个有窗口、按钮和文本框的图形界面版本。
- 数据库存储:将文件存储替换为数据库存储(如 MySQL, SQLite),使用 JDBC 进行连接和操作,以获得更好的性能、安全性和数据管理能力。
- 更多功能:增加按专业、年龄等条件进行排序和统计的功能。
- 异常处理增强:对用户输入进行更严格的校验,防止非法输入导致程序崩溃。
