[Java实战项目]200+行代码构建多功能学生信息管理系统

    科技2022-07-10  173

    项目目标:

    1. 实现管理员(admin)登录 2. 实现三种学生信息查看方式 查看所有学生信息 根据ID查看学生所有信息 根据ID查看学生姓名 3. 添加学生信息 4. 删除学生信息 5. 实现两种修改学生信息方式 根据ID修改学生全部信息 根据ID修改学生指定信息

    0、项目实现规划

    思维规划

    磨刀不误砍柴工,在动手做一个完整的项目之前,我们最应该完成的是对项目的思路整理和功能规划。整体来看,整个项目类似于数据库的增删改查功能。



    用户通过控制台操作main,完成增删改查等功能或退出系统。虽然系统用户校验和增删改查在实现方式上是平级,但是从逻辑上,校验是优先于增删改查的,即先登录,再操作。

    代码规划

    代码规划神似将思维规划实例化,根据思维图的架构,我们很容易将思维图中的每一个功能对应每一个函数。



    函数名功能exitLogin退出系统userValidataLogin登录验证addStudentInfo添加学生信息selectStudentInfo查询学生信息delStudentInfo删除学生信息modifyStudentInfo修改学生信息

    == 一切准备就绪!让我们进入代码的世界吧!==

    1、非核心功能实现

    退出系统

    如果说密码验证是系统的入口,那么退出系统就像是进入系统的出口。为了保证系统的持续运行,而不是单一的方法调用,代码中往往会使用死循环,而退出系统这一出口,就十分重要。此外,整个系统中需要退出的情况不止一次,将其打包成方法,可读性高,且方便。

    //1、退出方法 public static int exitLogin() { System.out.println("exit."); return 0; }
    系统用户登录

    本次系统登录,仅实现了admin用户的admin密码验证,如果需要注册,可以使用ArrayList存储,如果需要多用户切换登录,则可以遍历ArrayList校验。这和后面核心功能当中的查看和修改方法类似。

    //2、登录验证方法 public static boolean userValidataLogin(Scanner sc) { System.out.println("欢迎登录!"); System.out.print("请输入用户名:"); String LoginUserName = sc.next(); System.out.print("请输入密码:"); String LoginUserPass = sc.next(); if (LoginUserName.equals("admin") && LoginUserPass.equals("admin")) { System.out.println("登陆成功!"); System.out.println("欢迎您:" + LoginUserName); System.out.println("验证成功!"); } else { System.out.println("账号或密码错误!!!请重新输入!"); userValidataLogin(sc); } return true; }

    2、核心功能实现

    main程序入口

    定义好登录和退出后,即可使用main方法测试调用,为了保持系统的连贯性和持续性,直接使用死循环重复运行。

    public class StudentManagerSystem { //登录选择部分 public static void main(String[] args) { System.out.println("---------------------------欢迎登录学生管理系统--------------------------"); System.out.println("1 登录 2 退出"); System.out.println("-----------------------------------------------------------------------"); Scanner sc = new Scanner(System.in); System.out.print("请选择(1 or 2):"); int userInputInt = sc.nextInt(); boolean flg = false; switch (userInputInt) { case 1: flg = userValidataLogin(sc); break; case 2: exitLogin(); break; }

    如果用户选择1,则调用验证方法,如果不通过,则递归调用(在userValidataLogin方法中)。如果选择2,则调用退出方法。 1:登录失败,递归调用自己再次验证;2:IDEA的智能提示,如果有递归,则会出现此符号


    main+登录验证方法+退出系统方法测试效果:


    完成验证后进入系统,运行方式为持续运行。

    //密码正确,登录成功! while (flg) { System.out.println("---------------------------请选择操作的信息对应的数字--------------------------"); System.out.println("1.查看 2.添加 3.删除 4.修改 5.退出 -"); System.out.println("-----------------------------------------------------------------------------"); System.out.print("请选择:"); int userInt = sc.nextInt(); //提前断定用户是否想要退出 if (userInt == 5) { exitLogin(); break; } else if (userInt == 4) { //等于4,则调用修改学生信息函数 int tmpRetInt = modifyStudentInfo(sc); if (tmpRetInt == -1) { //接收返回值,如果等于-1,则表示用户需要退出 exitLogin(); break; } } switch (userInt) {//正常调用 case 1: selectStudentInfo(sc); break; case 2: addStudentInfo(sc); break; case 3: delStudentInfo(sc); break; default: System.out.println("输入有误!请重新输入!"); } } }
    查看学生信息

    先声明一个全局集合,用于存储所有学生信息

    public class StudentManagerSystem { //定义一个空集合,定义单个元素为列表 static List<String[]> stuArrayList = new ArrayList<>(); //4、查询学生信息 public static void selectStudentInfo(Scanner sc) { System.out.println("---------------------------请选择操作的信息对应的数字--------------------------"); System.out.println("1.查看所有学生信息 2.根据ID查询学生信息 3.根据ID查询学生姓名 4.返回上一层 "); System.out.println("-----------------------------------------------------------------------------"); System.out.print("请选择:"); int userInputInt = sc.nextInt(); //如果等于4,直接退出 if (userInputInt == 4) { return; } switch (userInputInt) { case 1: System.out.println("----------------------------------所有学生信息--------------------------------"); System.out.println("|学号 |姓名 |年龄 |性别 |年级 |电话 |Email |地址"); for (int i = 0; i < stuArrayList.size(); i++) { System.out.println(Arrays.toString(stuArrayList.get(i))); } break; case 2: System.out.print("请输入要查询的学生ID:"); String userInputStrID = sc.next(); for (int listIndex = 0; listIndex < stuArrayList.size(); listIndex++) { if ((stuArrayList.get(listIndex))[0].equals(userInputStrID)) { System.out.println("----------------------------------该生所有信息--------------------------------"); System.out.println("|学号 |姓名 |年龄 |性别 |年级 |电话 |Email |地址"); System.out.println(Arrays.toString(stuArrayList.get(listIndex))); } else { System.out.println("学生ID不存在!"); } } break; case 3: System.out.print("请输入要查询的学生ID:"); String userInputStrIDName = sc.next(); for (int listIndex = 0; listIndex < stuArrayList.size(); listIndex++) { if ((stuArrayList.get(listIndex))[0].equals(userInputStrIDName)) { System.out.println(("学号" + userInputStrIDName + ",\t" + "姓名" + (stuArrayList.get(listIndex))[1])); } else { System.out.println("学生ID不存在!"); } } break; default: System.out.println("输入有误!请重新输入!"); } selectStudentInfo(sc); }

    一套下来比较简单,为了方便,集合的单个的元素为String类型的列表,方便管理。 需要注意的是如果把返回上一层的功能嵌套到case当中,那么可能会穿透,所以直接在switch外面使用retuen,提前断定用户是否需要退出。

    添加学生信息
    //3、添加学生信息主方法 public static void addStudentInfo(Scanner sc) { //先判断一下集合是否为空,为空直接调用方法 if (stuArrayList.isEmpty()) { System.out.println("学生集合为空!直接添加!"); addInfoFunc(sc); } else { //非空,先判断ID是否重复 System.out.print("请输入学生ID:"); String userString = sc.next(); //先把所有的学号取出来存到列表当中 String[] stuIDList = new String[stuArrayList.size()]; for (int listIndex = 0; listIndex < stuArrayList.size(); listIndex++) { stuIDList[listIndex] = (stuArrayList.get(listIndex))[0]; } //判断输入的ID是否已存在 if (Arrays.asList(stuIDList).contains(userString)) { System.out.println("此ID" + userString + "已存在,请重新输入!"); addStudentInfo(sc); } else { System.out.println("ID校验不冲突,请添加学生信息!"); addInfoFunc(sc); } } } //3.1 添加学生信息副方法,抽取的重复代码 public static void addInfoFunc(Scanner sc) { String[] tmpStuInfoList = new String[8];//临时数组,用来存储,然后装到集合 System.out.print("请输入学生ID:"); String stuID = sc.next(); tmpStuInfoList[0] = stuID; //name System.out.print("请输入学生姓名:"); String stuName = sc.next(); tmpStuInfoList[1] = stuName; System.out.print("请输入学生性别:"); String stuSex = sc.next(); tmpStuInfoList[2] = stuSex; System.out.print("请输入学生年龄:"); String stuAge = sc.next(); tmpStuInfoList[3] = stuAge; System.out.print("请输入学生所属年级(只能初级、中级、高级):"); String stuClass = sc.next(); tmpStuInfoList[4] = stuClass; System.out.print("请输入学生地址:"); String stuAddress = sc.next(); tmpStuInfoList[5] = stuAddress; System.out.print("请输入学生联系方式(11位手机号):"); String stuPhone = sc.next(); tmpStuInfoList[6] = stuPhone; System.out.print("请输入学生电子邮箱:(包含@和.com)"); String stuEmail = sc.next(); tmpStuInfoList[7] = stuEmail; stuArrayList.add(tmpStuInfoList); System.out.println("写入成功!系统将自动返回上层目录~"); }

    每次运行的时候,学生集合总是初始化为空集合,如果不加以判断,那么系统就无法进入添加流程中,所以提前判断是否是空集合,空则直接添加。 本方法逻辑:先判断是否是空,空则直接添加;非空先判断是否ID重复,重复则递归本方法,重新输入;不重复则开始添加学生信息。


    修改学生信息
    //6、修改学生信息 public static int modifyStudentInfo(Scanner sc) { System.out.println("---------------------------请选择操作的信息对应的数字--------------------------"); System.out.println("1.根据ID修改学生全部信息 2.根据ID修改学生部分信息 3.返回上级目录 4.退出系统"); System.out.println("-----------------------------------------------------------------------------"); System.out.print("请选择:"); int userInputInt = sc.nextInt(); switch (userInputInt) { case 1: System.out.println("建议直接删除学生信息,再重新录入信息!"); System.out.println("请输入您要修改(删除重录)的学生ID:"); //先调用删除方法,删除学生信息 delStudentInfo(sc); //添加学生信息: addStudentInfo(sc); break; case 2: System.out.print("请输入您要修改的学生ID:"); String userInputStr = sc.next(); for (int listIndex = 0; listIndex < stuArrayList.size(); listIndex++) { if (stuArrayList.get(listIndex)[0].equals(userInputStr)) { System.out.print("请输入您要修改的属性:"); String userInputStuInfo = sc.next(); System.out.print("请输入修改后的值:"); String userInputStuFinalInfo = sc.next(); //用一个列表存储所有的属性 String[] tmpInfoList = {"id", "name", "age", "sex", "class", "phone", "Email", "address"}; if (Arrays.asList(tmpInfoList).contains(userInputStuInfo)) { //索引值 int tmpIndex = Arrays.asList(tmpInfoList).indexOf(userInputStuInfo); //修改集合当中对应的索引值的属性 (stuArrayList.get(listIndex))[tmpIndex] = userInputStuFinalInfo; System.out.println("修改成功!修改属性" + userInputStr + "为:" + userInputStuFinalInfo); } else { System.out.println("您输入的学生属性不存在,请重新输入!"); } } else { System.out.println("您输入的学生ID不存在,请重新输入!"); } } break; //返回上级目录 == 退出本函数 case 3: break; //退出本函数,并在调用函数的代码后面执行退出函数 case 4: return -1; } return 0; }

    方法逻辑:用户选择根据ID修改学生所有信息的时候,先调用删除方法,再调用添加方法;用户选择ID修改学生部分信息的时候,遍历集合,将内存地址转化为数据进行判断,通过一一对应的索引进行修改;如果用户选择返回上一层,则直接break(奇怪为什么这里不会穿透…),如果需要退出系统,则先退出本方法,再返回到main方法中判断返回值,如果为-1,则调用退出方法。 需要注意的是,我们在判断用户到底想修改哪个属性的时候,是用一个列表来存储所有的属性,这个属性需要和我们存储到集合当中的列表的顺序一致,这是为了方便直接通过索引修改。


    删除学生信息
    //5、删除学生信息 public static void delStudentInfo(Scanner sc) { if (stuArrayList.size() == 0) { System.out.println("学生集合为空,请先添加信息!"); return; } else if (stuArrayList.size() != 0) { System.out.print("请输入要删除的学生ID:"); String userInpStuID = sc.next(); for (int listIndex = 0; listIndex < stuArrayList.size(); listIndex++) { if ((stuArrayList.get(listIndex))[0].equals(userInpStuID)) { //remove传入值,故先将查询值 *其实是内存地址 String[] tmpStrList = stuArrayList.get(listIndex); //删除 stuArrayList.remove(tmpStrList); System.out.println("删除成功!系统即将返回上一层!"); } else { System.out.println("学生ID不存在,请重新输入!"); } } } }

    方法逻辑:遍历循环学生数据集合,查找用户传入的ID值,如果存在,则用一个临时变量存储该Array的值,然后传入ArrayList的remove方法;如果不存在,则提示。


    测试一下:


    完整代码已发到个人资源,可查找下载或自行拼接本文代码…难度不大,建议手敲


    End

    Processed: 0.016, SQL: 8