杰瑞科技汇

Java学生成绩管理系统源代码如何实现?

这套系统采用了经典的 MVC (Model-View-Controller) 设计模式,代码结构清晰,易于理解和扩展,它使用 控制台 作为用户界面,通过 文件 (I/O) 来持久化数据,无需依赖任何数据库,非常适合学习和作为课程设计项目。

Java学生成绩管理系统源代码如何实现?-图1
(图片来源网络,侵删)

  1. 学生信息管理:添加、删除、修改、查询学生信息(学号、姓名、性别)。
  2. 成绩管理:为每个学生添加多门课程的成绩(课程名、分数)。
  3. 数据持久化:所有学生信息和成绩数据会自动保存到 students.dat 文件中,程序关闭后重新打开,数据依然存在。
  4. 统计功能
    • 计算单个学生的总分和平均分。
    • 计算指定课程的全班平均分、最高分和最低分。
  5. 界面友好:提供清晰的菜单导航,操作简单。

项目结构

为了方便理解,我们将代码组织在几个不同的包中:

StudentManagementSystem/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   ├── model/          // Model 层:数据模型
│   │   │   │   ├── Course.java
│   │   │   │   ├── Student.java
│   │   │   │   └── StudentManagementSystem.java (核心业务逻辑)
│   │   │   ├── view/           // View 层:用户界面
│   │   │   │   └── MainView.java
│   │   │   ├── controller/     // Controller 层:控制逻辑
│   │   │   │   └── MainController.java
│   │   │   └── Main.java       // 程序入口
│   │   └── resources/
│   └── test/

源代码详解

以下是每个文件的完整源代码。

Model 层

model/Student.java

学生实体类,包含学生的基本信息和成绩列表。

package model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class Student implements Serializable {
    private String studentId;
    private String name;
    private String gender;
    private List<Course> courses;
    public Student(String studentId, String name, String gender) {
        this.studentId = studentId;
        this.name = name;
        this.gender = gender;
        this.courses = new ArrayList<>();
    }
    // Getters and Setters
    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 String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public List<Course> getCourses() {
        return courses;
    }
    public void addCourse(Course course) {
        this.courses.add(course);
    }
    public void removeCourse(String courseName) {
        this.courses.removeIf(c -> c.getCourseName().equals(courseName));
    }
    public Course findCourse(String courseName) {
        for (Course c : courses) {
            if (c.getCourseName().equals(courseName)) {
                return c;
            }
        }
        return null;
    }
    public double getTotalScore() {
        return courses.stream().mapToDouble(Course::getScore).sum();
    }
    public double getAverageScore() {
        if (courses.isEmpty()) {
            return 0.0;
        }
        return getTotalScore() / courses.size();
    }
    @Override
    public String toString() {
        return "Student{" +
                "studentId='" + studentId + '\'' +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", courses=" + courses +
                '}';
    }
}

model/Course.java

课程实体类,包含课程名和分数。

Java学生成绩管理系统源代码如何实现?-图2
(图片来源网络,侵删)
package model;
import java.io.Serializable;
public class Course implements Serializable {
    private String courseName;
    private double score;
    public Course(String courseName, double score) {
        this.courseName = courseName;
        this.score = score;
    }
    // Getters and Setters
    public String getCourseName() {
        return courseName;
    }
    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }
    @Override
    public String toString() {
        return "Course{" +
                "courseName='" + courseName + '\'' +
                ", score=" + score +
                '}';
    }
}

model/StudentManagementSystem.java

核心业务逻辑类,负责管理所有学生和文件读写操作。

package model;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class StudentManagementSystem implements Serializable {
    private List<Student> students;
    private static final String FILE_NAME = "students.dat";
    public StudentManagementSystem() {
        this.students = new ArrayList<>();
        loadData();
    }
    public void addStudent(Student student) {
        students.add(student);
        saveData();
    }
    public void removeStudent(String studentId) {
        students.removeIf(s -> s.getStudentId().equals(studentId));
        saveData();
    }
    public Student findStudent(String studentId) {
        for (Student s : students) {
            if (s.getStudentId().equals(studentId)) {
                return s;
            }
        }
        return null;
    }
    public List<Student> getAllStudents() {
        return students;
    }
    public void updateStudent(Student updatedStudent) {
        for (int i = 0; i < students.size(); i++) {
            if (students.get(i).getStudentId().equals(updatedStudent.getStudentId())) {
                students.set(i, updatedStudent);
                saveData();
                return;
            }
        }
    }
    // 统计功能
    public double calculateCourseAverage(String courseName) {
        List<Double> scores = students.stream()
                .map(s -> s.findCourse(courseName))
                .filter(c -> c != null)
                .map(Course::getScore)
                .collect(Collectors.toList());
        if (scores.isEmpty()) return 0.0;
        return scores.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
    }
    public double calculateCourseMax(String courseName) {
        return students.stream()
                .map(s -> s.findCourse(courseName))
                .filter(c -> c != null)
                .mapToDouble(Course::getScore)
                .max().orElse(0.0);
    }
    public double calculateCourseMin(String courseName) {
        return students.stream()
                .map(s -> s.findCourse(courseName))
                .filter(c -> c != null)
                .mapToDouble(Course::getScore)
                .min().orElse(0.0);
    }
    // 文件操作
    private void saveData() {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME))) {
            oos.writeObject(students);
        } catch (IOException e) {
            System.err.println("Error saving data: " + e.getMessage());
        }
    }
    @SuppressWarnings("unchecked")
    private void loadData() {
        File file = new File(FILE_NAME);
        if (file.exists()) {
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME))) {
                students = (List<Student>) ois.readObject();
            } catch (IOException | ClassNotFoundException e) {
                System.err.println("Error loading data: " + e.getMessage());
                students = new ArrayList<>(); // 如果加载失败,初始化一个空列表
            }
        }
    }
}

View 层

view/MainView.java

负责与用户交互,显示菜单和接收输入。

package view;
import model.Course;
import model.Student;
import model.StudentManagementSystem;
import java.util.List;
import java.util.Scanner;
public class MainView {
    private Scanner scanner;
    private StudentManagementSystem sms;
    public MainView(StudentManagementSystem sms) {
        this.sms = sms;
        this.scanner = new Scanner(System.in);
    }
    public void showMenu() {
        while (true) {
            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("6. 计算学生总分和平均分");
            System.out.println("7. 课程统计(平均分、最高分、最低分)");
            System.out.println("8. 显示所有学生");
            System.out.println("0. 退出系统");
            System.out.println("====================================");
            System.out.print("请选择操作: ");
            int choice;
            try {
                choice = Integer.parseInt(scanner.nextLine());
            } catch (NumberFormatException e) {
                System.out.println("输入无效,请输入数字!");
                continue;
            }
            switch (choice) {
                case 1:
                    addStudent();
                    break;
                case 2:
                    removeStudent();
                    break;
                case 3:
                    updateStudent();
                    break;
                case 4:
                    findStudent();
                    break;
                case 5:
                    addOrUpdateScore();
                    break;
                case 6:
                    calculateStudentStats();
                    break;
                case 7:
                    calculateCourseStats();
                    break;
                case 8:
                    displayAllStudents();
                    break;
                case 0:
                    System.out.println("感谢使用,再见!");
                    return;
                default:
                    System.out.println("无效的选择,请重新输入!");
            }
        }
    }
    private void addStudent() {
        System.out.println("--- 添加学生 ---");
        System.out.print("请输入学号: ");
        String id = scanner.nextLine();
        if (sms.findStudent(id) != null) {
            System.out.println("该学号已存在!");
            return;
        }
        System.out.print("请输入姓名: ");
        String name = scanner.nextLine();
        System.out.print("请输入性别: ");
        String gender = scanner.nextLine();
        sms.addStudent(new Student(id, name, gender));
        System.out.println("学生添加成功!");
    }
    private void removeStudent() {
        System.out.println("--- 删除学生 ---");
        System.out.print("请输入要删除的学生学号: ");
        String id = scanner.nextLine();
        if (sms.findStudent(id) != null) {
            sms.removeStudent(id);
            System.out.println("学生删除成功!");
        } else {
            System.out.println("未找到该学号的学生!");
        }
    }
    private void updateStudent() {
        System.out.println("--- 修改学生信息 ---");
        System.out.print("请输入要修改的学生学号: ");
        String id = scanner.nextLine();
        Student student = sms.findStudent(id);
        if (student == null) {
            System.out.println("未找到该学号的学生!");
            return;
        }
        System.out.println("当前信息: " + student);
        System.out.print("请输入新姓名 (回车保持原值): ");
        String name = scanner.nextLine();
        if (!name.isEmpty()) student.setName(name);
        System.out.print("请输入新性别 (回车保持原值): ");
        String gender = scanner.nextLine();
        if (!gender.isEmpty()) student.setGender(gender);
        sms.updateStudent(student);
        System.out.println("学生信息更新成功!");
    }
    private void findStudent() {
        System.out.println("--- 查询学生信息 ---");
        System.out.print("请输入要查询的学生学号: ");
        String id = scanner.nextLine();
        Student student = sms.findStudent(id);
        if (student != null) {
            System.out.println(student);
        } else {
            System.out.println("未找到该学号的学生!");
        }
    }
    private void addOrUpdateScore() {
        System.out.println("--- 添加/修改学生成绩 ---");
        System.out.print("请输入学生学号: ");
        String studentId = scanner.nextLine();
        Student student = sms.findStudent(studentId);
        if (student == null) {
            System.out.println("未找到该学号的学生!");
            return;
        }
        System.out.print("请输入课程名: ");
        String courseName = scanner.nextLine();
        System.out.print("请输入分数: ");
        double score;
        try {
            score = Double.parseDouble(scanner.nextLine());
        } catch (NumberFormatException e) {
            System.out.println("分数格式错误!");
            return;
        }
        Course course = student.findCourse(courseName);
        if (course != null) {
            course.setScore(score);
            System.out.println("成绩更新成功!");
        } else {
            student.addCourse(new Course(courseName, score));
            System.out.println("成绩添加成功!");
        }
        sms.updateStudent(student); // 保存更新
    }
    private void calculateStudentStats() {
        System.out.println("--- 计算学生总分和平均分 ---");
        System.out.print("请输入学生学号: ");
        String id = scanner.nextLine();
        Student student = sms.findStudent(id);
        if (student != null) {
            System.out.printf("学生 %s 的总分: %.2f, 平均分: %.2f\n",
                    student.getName(), student.getTotalScore(), student.getAverageScore());
        } else {
            System.out.println("未找到该学号的学生!");
        }
    }
    private void calculateCourseStats() {
        System.out.println("--- 课程统计 ---");
        System.out.print("请输入课程名: ");
        String courseName = scanner.nextLine();
        double avg = sms.calculateCourseAverage(courseName);
        double max = sms.calculateCourseMax(courseName);
        double min = sms.calculateCourseMin(courseName);
        System.out.printf("课程 '%s' 的统计结果:\n", courseName);
        System.out.printf("平均分: %.2f, 最高分: %.2f, 最低分: %.2f\n", avg, max, min);
    }
    private void displayAllStudents() {
        System.out.println("--- 所有学生信息 ---");
        List<Student> students = sms.getAllStudents();
        if (students.isEmpty()) {
            System.out.println("当前没有学生信息。");
        } else {
            for (Student s : students) {
                System.out.println(s);
            }
        }
    }
}

Controller 层

controller/MainController.java

连接 Model 和 View,是整个应用的协调者。

package controller;
import model.StudentManagementSystem;
import view.MainView;
public class MainController {
    public static void main(String[] args) {
        // 1. 创建 Model 实例,它会自动加载数据
        StudentManagementSystem sms = new StudentManagementSystem();
        // 2. 创建 View 实例,并将 Model 传递给它
        MainView view = new MainView(sms);
        // 3. 启动用户界面
        view.showMenu();
    }
}

如何运行

  1. 环境准备:确保您的电脑上已安装 JDK (Java Development Kit) 和集成开发环境,如 IntelliJ IDEAEclipse

    Java学生成绩管理系统源代码如何实现?-图3
    (图片来源网络,侵删)
  2. 创建项目

    • 在您的 IDE 中创建一个新的 Java 项目。
    • 创建如上所示的包结构:model, view, controller
  3. 复制代码

    • 将上述 Student.java, Course.java, StudentManagementSystem.java 代码分别复制到 model 包中对应的文件里。
    • MainView.java 代码复制到 view 包中。
    • MainController.java 代码复制到 controller 包中。注意MainController.java 中的 public class MainController 应该改为 public class Main,或者直接把 main 方法放在 MainViewStudentManagementSystem 中,为了清晰,我们这里将其作为控制器,并命名为 Main,以下是修正后的 controller/Main.java
    package controller;
    import model.StudentManagementSystem;
    import view.MainView;
    public class Main { // 将类名改为 Main
        public static void main(String[] args) {
            // 1. 创建 Model 实例,它会自动加载数据
            StudentManagementSystem sms = new StudentManagementSystem();
            // 2. 创建 View 实例,并将 Model 传递给它
            MainView view = new MainView(sms);
            // 3. 启动用户界面
            view.showMenu();
        }
    }
  4. 编译和运行

    • 在 IDE 中找到 controller.Main 这个类,右键点击并选择 "Run 'Main.main()'"。
    • 程序启动后,您将看到一个命令行菜单,可以通过输入数字来选择不同的功能。

扩展建议

这个项目已经具备了基本功能,您还可以在此基础上进行扩展,

  • 图形用户界面:使用 Java Swing 或 JavaFX 开发一个图形界面,替代控制台界面,体验会更好。
  • 数据库存储:将文件存储方式替换为 MySQL、PostgreSQL 等关系型数据库,或者 MongoDB 等 NoSQL 数据库,这对于处理大量数据更为高效和稳定。
  • 更多统计功能:增加按成绩排序、查询不及格学生、生成成绩单等功能。
  • 用户权限管理:增加管理员和普通用户的区分,不同权限的用户拥有不同的操作范围。
  • 日志记录:增加日志功能,记录所有关键操作,便于追踪和排查问题。
分享:
扫描分享到社交APP
上一篇
下一篇