做任何项目都要先 “拆解需求、分模块实现”,学生管理系统也不例外:
1. 第一步:定义学生实体类
目的:现实中的 “学生” 是一个实体,有学号、姓名、年龄、班级等属性,在 Java 中需要用类来封装这些属性,这是面向对象中 “封装” 思想的体现。
核心操作:
定义私有成员变量(学号、姓名、年龄等,学号唯一,作为后续增删改查的标识)。
提供公共的getter/setter方法(私有变量不能直接外部访问,通过 get/set 操作属性,保证数据安全性)。
提供有参 / 无参构造方法(方便快速创建学生对象)。
重写toString()方法(默认打印对象地址,重写后可友好展示学生信息)。
2. 第二步:实现核心业务逻辑(增删改查,业务层
目的:封装所有对学生数据的操作,解耦 “数据操作” 和 “用户交互”,方便后续维护和扩展。
核心准备:使用ArrayList<Student>存储学生对象(相比数组,ArrayList 支持动态扩容,增删操作更便捷,适合新手),并将集合私有化(避免外部直接修改集合,保证数据安全)。
核心功能实现:
增加:先校验学号是否重复(避免数据冗余),不重复则将学生对象添加到集合。
删除:根据学号查找学生,存在则从集合中移除,不存在则提示用户。
修改:根据学号查找学生,存在则更新其姓名 / 年龄等属性,不存在则提示用户。
查询:分为 “查询所有学生” 和 “按学号查询单个学生”,满足不同查询需求。
3. 第三步:实现控制台用户交互(界面交互层)
目的:给用户提供操作入口,接收用户输入,调用业务层的增删改查方法,并将结果反馈给用户。
核心操作:
使用Scanner类接收用户输入(菜单选择、学生信息录入等)。
制作简易菜单(如 “1. 增加 2. 删除 3. 修改 4. 查询 5. 退出”)。
使用循环(while(true))让系统持续运行,直到用户选择退出。
对用户输入进行简单校验(如避免菜单选择输入非数字)。
4. 第四步:编写主程序入口(启动类)
目的:整合所有模块,启动学生管理系统。
核心操作:创建业务层对象和交互层逻辑,运行循环菜单,让系统正常工作。
二、具体代码实现(完整可运行,带详细注释)
下面分 3 个类实现,所有类放在同一个包下即可。
类 1:Student.java(学生实体类,封装数据)

/*学生实体类:封装学生的属性和行为,体现OOP的封装思想
 职责:只存储学生数据,不处理业务逻辑*/
public class Student {
    // 1. 私有成员变量(学号、姓名、年龄、班级),学号唯一标识学生
    private String id;   // 学号(用String更灵活,支持如"2026001"格式,避免int长度限制)
    private String name; // 姓名
    private int age;     // 年龄
    private String clazz; // 班级(避免和关键字class重名)

    // 2. 无参构造方法:方便后续反射、集合扩容等场景使用
    public Student() {
    }

    // 3. 有参构造方法:方便快速创建完整的学生对象
    public Student(String id, String name, int age, String clazz) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.clazz = clazz;
    }

    // 4. 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 getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    // 5. 重写toString()方法:默认打印对象地址,重写后友好展示学生信息
    @Override
    public String toString() {
        return "学生信息:" +
                "学号='" + id + '\'' +
                ", 姓名='" + name + '\'' +
                ", 年龄=" + age +
                ", 班级='" + clazz + '\'';
    }
}

类 2:StudentManager.java(业务逻辑类,实现增删改查)

import java.util.ArrayList;
import java.util.List;

/**
 * 学生管理业务类:封装所有增删改查逻辑,是系统的核心
 * 职责:只处理业务逻辑,不与用户直接交互
 */
public class StudentManager {
    // 1. 私有化ArrayList集合,存储学生对象,仅本类可访问,保证数据安全
    // 泛型<Student>:限定集合只能存储Student对象,避免类型错误
    private List<Student> studentList = new ArrayList<>();

    // 功能1:增加学生
    public boolean addStudent(Student student) {
        // 先校验学号是否重复(核心:避免重复数据)
        if (findStudentById(student.getId()) != null) {
            // 学号已存在,返回false表示添加失败
            return false;
        }
        // 学号不存在,添加到集合,返回true表示添加成功
        studentList.add(student);
        return true;
    }

    // 功能2:删除学生(根据学号)
    public boolean deleteStudent(String id) {
        // 先查找该学号的学生
        Student student = findStudentById(id);
        if (student != null) {
            // 找到学生,移除出集合,返回true表示删除成功
            studentList.remove(student);
            return true;
        }
        // 未找到学生,返回false表示删除失败
        return false;
    }

    // 功能3:修改学生(根据学号,更新其他属性)
    public boolean updateStudent(String id, Student newStudent) {
        // 先查找该学号的学生
        Student oldStudent = findStudentById(id);
        if (oldStudent != null) {
            // 找到学生,更新姓名、年龄、班级(学号不建议修改,作为唯一标识)
            oldStudent.setName(newStudent.getName());
            oldStudent.setAge(newStudent.getAge());
            oldStudent.setClazz(newStudent.getClazz());
            return true;
        }
        // 未找到学生,返回false表示修改失败
        return false;
    }

    // 功能4:查询单个学生(根据学号)
    public Student findStudentById(String id) {
        // 遍历集合,查找学号匹配的学生
        for (Student student : studentList) {
            // 字符串比较用equals(),不能用==(==比较地址,equals比较内容)
            if (student.getId().equals(id)) {
                // 找到学生,返回该学生对象
                return student;
            }
        }
        // 遍历完未找到,返回null
        return null;
    }

    // 功能5:查询所有学生
    public List<Student> findAllStudents() {
        // 返回集合的拷贝?不,新手直接返回原集合(简化),后续可优化为返回不可变集合
        return studentList;
    }

    // 辅助方法:判断集合是否为空(方便交互层提示用户)
    public boolean isStudentListEmpty() {
        return studentList.isEmpty();
    }
}

类 3:StudentSystem.java(主程序类,实现用户交互 + 启动系统)

import java.util.List;
import java.util.Scanner;

/**
 * 学生管理系统主类:实现用户交互,调用业务层方法,是系统的入口
 * 职责:只处理用户交互,不处理核心业务逻辑
 */
public class StudentSystem {
    // 1. 创建Scanner对象,接收用户输入(全局使用,避免重复创建)
    private static Scanner scanner = new Scanner(System.in);
    // 2. 创建业务层对象,调用增删改查方法
    private static StudentManager studentManager = new StudentManager();

    public static void main(String[] args) {
        // 系统启动入口,循环展示菜单
        System.out.println("===== 学生管理系统启动 =====");
        while (true) {
            // 打印菜单
            showMenu();
            // 接收用户菜单选择
            String choice = scanner.next();
            // 分支判断,执行对应功能
            switch (choice) {
                case "1":
                    addStudentUI();
                    break;
                case "2":
                    deleteStudentUI();
                    break;
                case "3":
                    updateStudentUI();
                    break;
                case "4":
                    findAllStudentsUI();
                    break;
                case "5":
                    System.out.println("===== 退出学生管理系统,感谢使用 =====");
                    // 关闭Scanner,退出程序
                    scanner.close();
                    System.exit(0);
                    break;
                default:
                    System.out.println("输入错误,请选择1-5之间的选项!");
            }
        }
    }

    // 辅助方法:展示菜单
    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("============================");
        System.out.print("请输入你的选择:");
    }

    // 交互功能1:增加学生的界面逻辑
    private static void addStudentUI() {
        System.out.println("\n===== 增加学生 =====");
        // 接收学生信息
        System.out.print("请输入学生学号:");
        String id = scanner.next();
        System.out.print("请输入学生姓名:");
        String name = scanner.next();
        System.out.print("请输入学生年龄:");
        int age = scanner.nextInt();
        scanner.nextLine(); // 吸收换行符,避免后续输入异常
        System.out.print("请输入学生班级:");
        String clazz = scanner.nextLine();

        // 创建学生对象
        Student student = new Student(id, name, age, clazz);
        // 调用业务层增加方法
        boolean result = studentManager.addStudent(student);
        // 反馈结果给用户
        if (result) {
            System.out.println("增加学生成功!");
        } else {
            System.out.println("该学号已存在,增加学生失败!");
        }
    }

    // 交互功能2:删除学生的界面逻辑
    private static void deleteStudentUI() {
        System.out.println("\n===== 删除学生 =====");
        // 先判断集合是否为空
        if (studentManager.isStudentListEmpty()) {
            System.out.println("当前无学生数据,无法删除!");
            return;
        }
        // 接收学号
        System.out.print("请输入要删除的学生学号:");
        String id = scanner.next();
        // 调用业务层删除方法
        boolean result = studentManager.deleteStudent(id);
        // 反馈结果
        if (result) {
            System.out.println("删除学生成功!");
        } else {
            System.out.println("该学号不存在,删除学生失败!");
        }
    }

    // 交互功能3:修改学生的界面逻辑
    private static void updateStudentUI() {
        System.out.println("\n===== 修改学生 =====");
        // 先判断集合是否为空
        if (studentManager.isStudentListEmpty()) {
            System.out.println("当前无学生数据,无法修改!");
            return;
        }
        // 接收要修改的学号
        System.out.print("请输入要修改的学生学号:");
        String id = scanner.next();
        // 接收新的学生信息
        System.out.print("请输入新的学生姓名:");
        String newName = scanner.next();
        System.out.print("请输入新的学生年龄:");
        int newAge = scanner.nextInt();
        scanner.nextLine(); // 吸收换行符
        System.out.print("请输入新的学生班级:");
        String newClazz = scanner.nextLine();

        // 创建新的学生对象(存储新属性)
        Student newStudent = new Student(id, newName, newAge, newClazz);
        // 调用业务层修改方法
        boolean result = studentManager.updateStudent(id, newStudent);
        // 反馈结果
        if (result) {
            System.out.println("修改学生成功!");
        } else {
            System.out.println("该学号不存在,修改学生失败!");
        }
    }

    // 交互功能4:查询所有学生的界面逻辑
    private static void findAllStudentsUI() {
        System.out.println("\n===== 查询所有学生 =====");
        // 先判断集合是否为空
        if (studentManager.isStudentListEmpty()) {
            System.out.println("当前无学生数据!");
            return;
        }
        // 调用业务层查询所有方法,获取学生列表
        List<Student> studentList = studentManager.findAllStudents();
        // 遍历打印所有学生信息
        for (Student student : studentList) {
            // 直接打印student,会调用重写后的toString()方法
            System.out.println(student);
        }
        System.out.println("===== 查询完成,共" + studentList.size() + "名学生 =====");
    }
}

三、为什么要这么做?
为什么用String存储学号,而不是int?
学号可能包含前缀(如 “2026-001”)、或长度超过int范围(int最大为 2147483647),String更灵活,能满足更多场景需求。
为什么要校验学号唯一性?
学号是学生的唯一标识,重复的学号会导致后续修改、删除时无法准确找到目标学生,造成数据混乱,这是实际项目中 “数据唯一性” 的基础要求。
为什么字符串比较用equals(),而不是==?
==比较的是对象的内存地址,两个不同的String对象即使内容相同,地址也不同;equals()比较的是字符串的实际内容,符合学号比较的需求。
为什么要将ArrayList私有化?
体现 “封装” 思想,避免外部类直接修改集合(如直接调用clear()清空所有数据),保证数据安全,所有对集合的操作都必须通过业务层提供的方法进行,便于控制和维护。
为什么要重写toString()方法?
默认情况下,打印对象会输出 “类名 @哈希值”(如Student@1b6d3586),无法直观展示学生信息,重写后可以友好地打印学生的所有属性,方便调试和用户查看。
四、注意事项
输入数据合法性校验:
上述代码未处理 “年龄输入非数字” 的情况(如用户输入 “abc” 作为年龄,会抛出InputMismatchException),新手后续可通过try-catch捕获异常,提升程序健壮性。
可增加 “姓名不能为空”“年龄必须大于 0” 等校验,避免无效数据录入。
数据持久化问题:
上述系统的数据存储在内存中,程序退出后数据会丢失,新手后续可学习IO流(将数据写入文件)或JDBC(将数据存入数据库,如 MySQL),实现数据永久保存。
代码规范性:
类名、方法名遵循 Java 驼峰命名法(类名首字母大写,方法名首字母小写),如StudentManager、addStudent。
适当添加注释,尤其是核心业务逻辑,方便自己后续阅读和他人协作。
避免重复创建对象:
Scanner和StudentManager对象在主类中全局创建一次即可,避免在每个方法中重复创建,浪费内存资源。
菜单循环的退出逻辑:
使用System.exit(0)正常退出程序,避免无限循环无法终止,同时关闭Scanner资源,避免资源泄露。
五、做学生管理系统可以培养项目思维和逻辑思维:
学会将 “学生管理系统” 这个复杂需求拆解为 “实体类”“业务层”“交互层” 等简单模块,逐步实现,培养 “分而治之” 的项目开发思维,为后续开发复杂项目铺路。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐