Java实现学生管理系统(基于控制台的增删改查)

学生管理系统(基于控制台的增删改查)

要求:使用List集合存储自定义的对象集合,并熟练使用List集合的中常用方法实现相关的操作。

Java环境:jdk 17

IDE :Idea 2021.1.3

目录:

文章目录

  • 学生管理系统(基于控制台的增删改查)
    • 目录:
    • 一、定义的一个Student映射类
    • 二、在主类中实现的相关代码
    • 三、提出问题
      • 1、是否可以继续简化代码?
      • 2、为什么会在方法getId中使用Integer包装类而不用int?
      • 3、为什么定义了好几个全局变量?
    • 四、与直接操作数据库的增删改查的相同点
    • 五、总结

一、定义的一个Student映射类

package test05;

import lombok.Data;
import java.io.Serial;
import java.io.Serializable;

/**
 * @BelongsPackage: Java
 * @BelongsProject: test05
 * @author: ZhengHao
 * @CreateTime: 2022-11-02  13:39
 * @LastUpdateTime: 2022-11-03  13:52
 * @Description: 学生有关信息的字段,采用了lombok实现字段的封装等操作
 * @Version: 1.0
 */
@Data
public class Student implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 学号
     */
    private String Id;

    /**
     * 学生姓名
     */
    private String name;

    /**
     * 学生年龄
     */
    private Integer age;

    /**
     * 学生居住地
     */
    private String address;
}

注意:类中用了Lombok插件注解开发,同时用到了序列化,如果你不想通过这种方式,可以使用下面不用注解与序列化的代码。

package test05;

/**
 * @BelongsProject: Java
 * @BelongsPackage: test05
 * @Author: ZhengHao
 * @CreateTime: 2022-11-03  19:14
 * @LastUpdateTime: 2022-11-03  19:14
 * @Description: TODO
 * @Version: 1.0
 */
public class Student {
    /**
     * 学号
     */
    private String Id;

    /**
     * 学生姓名
     */
    private String name;

    /**
     * 学生年龄
     */
    private Integer age;

    /**
     * 学生居住地
     */
    private String address;

    public String getId() {
        return Id;
    }

    public void setId(String id) {
        Id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

其中的有参和无参的构造函数可以根据需要增加

二、在主类中实现的相关代码

package test05;

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

/**
 * @BelongsProject: Java
 * @BelongsPackage: test05
 * @Author: ZhengHao
 * @CreateTime: 2022-11-02  12:41
 * @LastUpdateTime: 2022-11-03  15:20
 * @Description: 基于控制台的学生管理系统,实现传统的增删改查(CURD)
 * @Version: 1.0
 */
public class StudentManageSystem {

    /**
     * 全局变量申请一个列表用于存储数据
     */
    private static final List<Student> list = new ArrayList<>();

    /**
     * 1、Scanner语句作为全局变量的主要原因是:
     * 在函数中,声明了一个 scanner 对象,并且调用了 close 方法,
     * 再次启动 scanner 的时候(或者在另一个函数中重新启动 scanner 时),就会遇到异常!
     * 2、根本原因:系统资源一旦释放就不能再开启了,所以只有确定不在使用系统的时候,才能将流关闭。
     */
    private static final Scanner scanner = new Scanner(System.in);

    /**
     * 全局变量定义一个供选择的数字
     */
    private static int num;

    /**
     * 全局定义一个bool变量
     */
    private static boolean flag = false;

    public static void main(String[] args) {
        while (true) {
            print();
            // switch语句采用了简化的方式,类似于lambada表达式的写法(要求jdk>=12,Jdk8可能会报错,下面有介绍解决方法)
            switch (num) {
                case 1 -> Read();
                case 2 -> add();
                case 3 -> del();
                case 4 -> update();
                case 5 -> System.exit(0);
            }
        }
    }

    /**
     * 输出管理系统的介绍
     */
    public static void print() {
        String sb = """
                ----------欢迎来到学生管理系统-----------
                1 查看所有学生
                2 添加学生
                3 删除学生
                4 修改学生
                5 退出
                请输入你的选择:""";
        System.out.println(sb);
        num = scanner.nextInt();
    }

    /**
     * 查
     */
    public static void Read() {
        if (list.isEmpty()) {
            System.out.println("不好意思,目前没有学生可查询,请回去重新选择你的操作");
        } else {
            for (Student student : list) {
                // 用StringBuilder的原因是为了增强代码可读性
                StringBuilder sb = new StringBuilder();
                sb.append("学号:")
                        .append(student.getId())
                        .append("\t姓名:")
                        .append(student.getName())
                        .append("\t年龄:")
                        .append(student.getAge())
                        .append("\t学生居住地:")
                        .append(student.getAddress());
                System.out.println(sb);
            }
        }
    }

    /**
     * 增
     */
    public static void add() {
        System.out.println("请输入学生学号:");
        String id = scanner.next();
        if (getId(id) == null) {
            Student student = new Student();
            student.setId(id);
            System.out.println("请输入学生姓名:");
            student.setName(scanner.next());
            System.out.println("请输入学生年龄:");
            student.setAge(scanner.nextInt());
            System.out.println("请输入学生居住地:");
            student.setAddress(scanner.next());
            list.add(student);
            System.out.println("添加学生成功");
        } else {
            System.out.println("请入添加重复的学生学号!!!");
        }
    }

    /**
     * 删
     */
    public static void del() {
        if (list.isEmpty()) {
            System.out.println("不好意思,目前没有学生可删除,请重新选择你的操作");
        } else {
            System.out.println("请输入你想删除学生的学号");
            String id = scanner.next();
            Integer index = getId(id);
            if (flag) {
                // 防止空指针异常的操作
                if (index == null) {
                    System.out.println("输入学生的学号不正确!!请仔细检查");
                } else {
                    list.remove(index.intValue());
                    System.out.println("删除成功");
                }
            } else {
                System.out.println("未查询到相关学生信息");
            }
        }
    }

    /**
     * 改
     */
    public static void update() {
        if (list.isEmpty()) {
            System.out.println("不好意思,目前没有学生可更新,请回去重新选择你的操作");
        } else {
            System.out.println("输入你想修改的学生的学号");
            String id = scanner.next();
            Integer index = getId(id);
            if (flag) {
                // 防止空指针异常
                if (index == null) {
                    System.out.println("输入学生的学号不正确!!请仔细检查");
                } else {
                    Student student = list.get(index);
                    System.out.println("请输入你修改的姓名");
                    student.setName(scanner.next());
                    System.out.println("请输入你修改的年龄");
                    student.setAge(scanner.nextInt());
                    System.out.println("请输入你修改的地址");
                    student.setAddress(scanner.next());
                    System.out.println("修改成功");
                }
            } else {
                System.out.println("未查询到相关学生信息");
            }
        }
    }

    /**
     * 查找学号是否在列表中
     *
     * @param id 学号
     * @return list列表的下标
     */
    public static Integer getId(String id) {
        Integer index = null;
        for (int i = 0; i < list.size(); i++) {
            Student student = list.get(i);
            if (student.getId().equals(id)) {
                flag = true;
                index = i;
                break;
            }
        }
        return index;
    }
}

switch语句进行了简化(要求:JDK 12 以上),如果是jdk8的话可以使用老的switch语句代码:

switch (num) {
    case 1:
    	Read();
    	break;
    case 2: 
        add();
        break;
    case 3:
        del();
        break;
    case 4:
        update();
        break;
    case 5:
        System.exit(0);
        //后面写不写break;都无所谓,因为虚拟机都已经退出了。
}

关于其中的代码功能,我在注释中已经写的够清楚了,请仔细阅读。

三、提出问题

1、是否可以继续简化代码?

答案是肯定的。有很多可以继续优化的地方。

2、为什么会在方法getId中使用Integer包装类而不用int?

先来看一下这个方法的代码:

public static Integer getId(String id){
        Integer index = null;
        for (int i = 0; i < list.size(); i++) {
            Student student = list.get(i);
            if (student.getId().equals(id)) {
                flag = true;
                index = i;
                break;
            }
        }
        return index;
    }

Integer首先是个包装类,可以自动拆箱和装箱。如果对包装类拆箱和装箱有疑问的话,建议点进去这个链接去看:包装类的详解 。其次我们可以返回一个null值。

在add()方法中调用getId这个方法时,我们首先需要判断在list中是否已经添加了此学生的学号,如果不用Integer包装类的话,用基类型int,假如我们第一次添加学生的学号为2222。然后继续添加学生也会调用add()方法,此时调用getId()方法得到的是返回值是0。无法通过判断index是否为0的判断是否有重复的学号发生。Integer包装类可以返回null,完美的解决了这个问题。

3、为什么定义了好几个全局变量?

主要都在一个类中,定义全局变量比用形参传值要方便而且还会减少一定的内存开销。

四、与直接操作数据库的增删改查的相同点

其实在很多时候,不管我们用的是Jdbc还是一些封装好的框架例如:Mybatis,在数据库中建好表,在访问这些数据中也是用一个映射类来做映射。然后用 list 将数据保存在列表中,将其返回给前端。

在此例子中,我自己默认将这里的学号作为一个类似于数据库中的主键,不可重复性,是唯一值来处理。

五、总结

自己只看标题,慢慢的将代码写出来,中间可能会遇到各种各样的问题,最好自己先思考一段时间慢慢的将其解决。更多的百度带来的只会让自己思维更加固定与死板。对自己写代码的能力不会提高,反而会下降。自己独立完成这个小练习后,对于后续的Java学习,特别是与数据库连接,老一套的增删改查有一定的思维帮助。

程序中可能还有一些问题,或者是一些代码的冗余性,请多见谅。

你可能感兴趣的:(Java,java,开发语言)