Java简易成绩管理系统开发指南
在很多基础Java学习场景中,开发简易成绩管理系统是巩固面向对象编程、集合操作、文件读写等知识点的经典实践。本文将带领大家从需求分析到代码实现,一步步完成一个具备基础增删改查功能的成绩管理系统。
一、需求分析
我们要开发的简易成绩管理系统需要实现以下核心功能:
- 添加学生成绩:录入学生的姓名、学号、各科成绩
- 查询学生成绩:根据学号或姓名查询学生的成绩信息
- 修改学生成绩:支持修改已录入的学生成绩数据
- 删除学生成绩:根据学号删除指定学生的成绩记录
- 成绩统计:计算单科平均分、最高分、最低分,以及学生的总分排名
- 数据持久化:将成绩数据保存到本地文件,程序重启后可读取历史数据
二、核心类设计
首先需要设计两个核心实体类,分别承载学生信息和成绩信息,符合面向对象的高内聚低耦合思想。
1. 学生类(Student)
学生类用于存储学生的基本信息和成绩列表,我们为类添加必要的属性和方法,同时重写equals和hashCode方法方便后续集合操作。
import java.util.ArrayList;
import java.util.List;
/**
* 学生实体类,存储学生基本信息和成绩
*/
public class Student {
// 学号
private String studentId;
// 姓名
private String name;
// 成绩列表,每个元素为科目名和对应成绩
private List<Score> scoreList;
public Student(String studentId, String name) {
this.studentId = studentId;
this.name = name;
this.scoreList = new ArrayList<>();
}
// 添加单科成绩
public void addScore(String subject, double score) {
scoreList.add(new Score(subject, score));
}
// 计算学生总分
public double calcTotalScore() {
double total = 0.0;
for (Score score : scoreList) {
total += score.getScore();
}
return total;
}
// getter和setter方法
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Score> getScoreList() {
return scoreList;
}
public void setScoreList(List<Score> scoreList) {
this.scoreList = scoreList;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Student student = (Student) obj;
return studentId.equals(student.studentId);
}
@Override
public int hashCode() {
return studentId.hashCode();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("学号:").append(studentId)
.append(",姓名:").append(name)
.append(",总分:").append(calcTotalScore())
.append(",各科成绩:");
for (Score score : scoreList) {
sb.append(score.getSubject()).append("=").append(score.getScore()).append(" ");
}
return sb.toString();
}
}2. 成绩类(Score)
成绩类用于关联科目和对应分数,结构比较简单,仅包含基本属性和getter/setter方法。
/**
* 成绩实体类,关联科目和分数
*/
public class Score {
// 科目名称
private String subject;
// 对应分数
private double score;
public Score(String subject, double score) {
this.subject = subject;
this.score = score;
}
// getter和setter方法
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}三、核心功能实现
接下来我们需要实现成绩管理的核心逻辑,包括学生信息的增删改查、成绩统计以及数据持久化操作,这里我们使用ArrayList作为内存数据存储容器。
1. 成绩管理核心类(ScoreManager)
该类封装所有业务逻辑,对外提供操作方法,内部维护学生列表,同时实现文件读写功能。
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* 成绩管理核心类,封装所有业务逻辑
*/
public class ScoreManager {
// 内存中学生列表
private List<Student> studentList;
// 数据持久化文件路径
private static final String DATA_FILE = "score_data.txt";
public ScoreManager() {
studentList = new ArrayList<>();
// 初始化时读取本地数据
loadData();
}
/**
* 添加学生
*/
public boolean addStudent(Student student) {
// 校验学号是否已存在
for (Student s : studentList) {
if (s.getStudentId().equals(student.getStudentId())) {
return false;
}
}
studentList.add(student);
return true;
}
/**
* 根据学号查询学生
*/
public Student getStudentById(String studentId) {
for (Student student : studentList) {
if (student.getStudentId().equals(studentId)) {
return student;
}
}
return null;
}
/**
* 根据姓名查询学生(支持重名)
*/
public List<Student> getStudentByName(String name) {
List<Student> result = new ArrayList<>();
for (Student student : studentList) {
if (student.getName().equals(name)) {
result.add(student);
}
}
return result;
}
/**
* 修改学生成绩
*/
public boolean updateStudentScore(String studentId, String subject, double newScore) {
Student student = getStudentById(studentId);
if (student == null) {
return false;
}
// 查找对应科目成绩并修改
for (Score score : student.getScoreList()) {
if (score.getSubject().equals(subject)) {
score.setScore(newScore);
return true;
}
}
// 如果科目不存在,新增该科目成绩
student.addScore(subject, newScore);
return true;
}
/**
* 删除学生
*/
public boolean deleteStudent(String studentId) {
Student student = getStudentById(studentId);
if (student != null) {
studentList.remove(student);
return true;
}
return false;
}
/**
* 计算单科统计信息(平均分、最高分、最低分)
*/
public String calcSubjectStat(String subject) {
List<Double> scores = new ArrayList<>();
for (Student student : studentList) {
for (Score score : student.getScoreList()) {
if (score.getSubject().equals(subject)) {
scores.add(score.getScore());
}
}
}
if (scores.isEmpty()) {
return "未找到科目" + subject + "的成绩记录";
}
double sum = 0.0;
double max = scores.get(0);
double min = scores.get(0);
for (Double score : scores) {
sum += score;
if (score > max) max = score;
if (score < min) min = score;
}
double avg = sum / scores.size();
return String.format("科目:%s,平均分:%.2f,最高分:%.2f,最低分:%.2f,参考人数:%d",
subject, avg, max, min, scores.size());
}
/**
* 按总分排名
*/
public List<Student> rankByTotalScore() {
List<Student> rankList = new ArrayList<>(studentList);
Collections.sort(rankList, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o2.calcTotalScore(), o1.calcTotalScore());
}
});
return rankList;
}
/**
* 保存数据到本地文件
*/
public void saveData() {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(DATA_FILE))) {
for (Student student : studentList) {
StringBuilder line = new StringBuilder();
line.append(student.getStudentId()).append(",")
.append(student.getName()).append(",");
for (Score score : student.getScoreList()) {
line.append(score.getSubject()).append("=").append(score.getScore()).append(";");
}
// 去除最后一个分号
if (line.charAt(line.length() - 1) == ';') {
line.deleteCharAt(line.length() - 1);
}
writer.write(line.toString());
writer.newLine();
}
} catch (IOException e) {
System.out.println("数据保存失败:" + e.getMessage());
}
}
/**
* 从本地文件读取数据
*/
private void loadData() {
File file = new File(DATA_FILE);
if (!file.exists()) {
return;
}
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
if (parts.length < 2) continue;
Student student = new Student(parts[0], parts[1]);
if (parts.length > 2) {
String[] scoreStrs = parts[2].split(";");
for (String scoreStr : scoreStrs) {
String[] scoreParts = scoreStr.split("=");
if (scoreParts.length == 2) {
student.addScore(scoreParts[0], Double.parseDouble(scoreParts[1]));
}
}
}
studentList.add(student);
}
} catch (IOException e) {
System.out.println("数据读取失败:" + e.getMessage());
}
}
/**
* 获取所有学生列表
*/
public List<Student> getAllStudents() {
return new ArrayList<>(studentList);
}
}四、控制台交互实现
最后我们实现一个控制台入口类,通过菜单交互的方式让用户操作系统,测试所有功能是否正常。
import java.util.List;
import java.util.Scanner;
/**
* 控制台交互入口类
*/
public class MainApp {
public static void main(String[] args) {
ScoreManager manager = new ScoreManager();
Scanner scanner = new Scanner(System.in);
boolean isRunning = true;
while (isRunning) {
printMenu();
System.out.print("请输入操作编号:");
String choice = scanner.nextLine();
switch (choice) {
case "1":
// 添加学生成绩
addStudentOper(manager, scanner);
break;
case "2":
// 查询学生成绩
queryStudentOper(manager, scanner);
break;
case "3":
// 修改学生成绩
updateScoreOper(manager, scanner);
break;
case "4":
// 删除学生
deleteStudentOper(manager, scanner);
break;
case "5":
// 成绩统计
statScoreOper(manager, scanner);
break;
case "6":
// 查看排名
showRank(manager);
break;
case "7":
// 保存数据并退出
manager.saveData();
System.out.println("数据已保存,程序退出");
isRunning = false;
break;
default:
System.out.println("无效的操作编号,请重新输入");
}
System.out.println();
}
scanner.close();
}
private static void printMenu() {
System.out.println("===== 简易成绩管理系统 =====");
System.out.println("1. 添加学生成绩");
System.out.println("2. 查询学生成绩");
System.out.println("3. 修改学生成绩");
System.out.println("4. 删除学生记录");
System.out.println("5. 成绩统计");
System.out.println("6. 查看总分排名");
System.out.println("7. 保存并退出");
System.out.println("===========================");
}
private static void addStudentOper(ScoreManager manager, Scanner scanner) {
System.out.print("请输入学号:");
String studentId = scanner.nextLine();
System.out.print("请输入姓名:");
String name = scanner.nextLine();
Student student = new Student(studentId, name);
System.out.print("请输入要添加的科目数量:");
int num = Integer.parseInt(scanner.nextLine());
for (int i = 0; i < num; i++) {
System.out.print("请输入第" + (i + 1) + "个科目名称:");
String subject = scanner.nextLine();
System.out.print("请输入" + subject + "的成绩:");
double score = Double.parseDouble(scanner.nextLine());
student.addScore(subject, score);
}
if (manager.addStudent(student)) {
System.out.println("学生成绩添加成功");
} else {
System.out.println("学号已存在,添加失败");
}
}
private static void queryStudentOper(ScoreManager manager, Scanner scanner) {
System.out.print("请选择查询方式:1.按学号 2.按姓名:");
String type = scanner.nextLine();
if ("1".equals(type)) {
System.out.print("请输入学号:");
Student student = manager.getStudentById(scanner.nextLine());
if (student != null) {
System.out.println("查询结果:" + student);
} else {
System.out.println("未找到该学号的学生");
}
} else if ("2".equals(type)) {
System.out.print("请输入姓名:");
List<Student> students = manager.getStudentByName(scanner.nextLine());
if (students.isEmpty()) {
System.out.println("未找到该姓名的学生");
} else {
System.out.println("查询结果:");
for (Student s : students) {
System.out.println(s);
}
}
} else {
System.out.println("无效的查询方式");
}
}
private static void updateScoreOper(ScoreManager manager, Scanner scanner) {
System.out.print("请输入要修改的学生学号:");
String studentId = scanner.nextLine();
System.out.print("请输入要修改的科目:");
String subject = scanner.nextLine();
System.out.print("请输入新的成绩:");
double newScore = Double.parseDouble(scanner.nextLine());
if (manager.updateStudentScore(studentId, subject, newScore)) {
System.out.println("成绩修改成功");
} else {
System.out.println("未找到该学生,修改失败");
}
}
private static void deleteStudentOper(ScoreManager manager, Scanner scanner) {
System.out.print("请输入要删除的学生学号:");
String studentId = scanner.nextLine();
if (manager.deleteStudent(studentId)) {
System.out.println("学生记录删除成功");
} else {
System.out.println("未找到该学生,删除失败");
}
}
private static void statScoreOper(ScoreManager manager, Scanner scanner) {
System.out.print("请输入要统计的科目名称:");
String subject = scanner.nextLine();
System.out.println(manager.calcSubjectStat(subject));
}
private static void showRank(ScoreManager manager) {
List<Student> rankList = manager.rankByTotalScore();
if (rankList.isEmpty()) {
System.out.println("暂无学生数据,无法排名");
return;
}
System.out.println("===== 总分排名 =====");
int rank = 1;
for (Student student : rankList) {
System.out.println("第" + rank + "名:" + student);
rank++;
}
}
}五、使用说明与扩展建议
运行MainApp类的main方法即可启动系统,按照菜单提示输入对应编号就能操作。程序会在当前目录生成score_data.txt文件存储数据,下次启动会自动读取。
如果需要扩展功能,可以考虑以下方向:
- 增加用户登录功能,区分管理员和普通用户权限
- 优化数据存储方式,改用数据库代替本地文件
- 增加图形用户界面,比如使用Swing或JavaFX实现可视化操作
- 完善输入校验,避免非法数据录入导致程序异常
- 增加成绩导出功能,支持将成绩导出为Excel文件
通过这个简易成绩管理系统的开发,可以很好地掌握Java基础语法、面向对象思想、集合操作、IO流等核心知识点,也可以作为后续复杂项目开发的基础框架。
Java成绩管理系统面向对象编程ArrayList文件读写控制台应用修改时间:2026-05-24 12:48:07