[Java实战项目]200+行代码构建多功能学生信息管理系统
[Java实战项目]200+行代码构建多功能学生信息管理系统
[Java实战项目]200+行代码构建多功能学生信息管理系统项目目标:
- 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
[Java实战项目]200+行代码构建多功能学生信息管理系统相关教程
-
图的基本介绍以及Java实现
图的基本介绍以及Java实现 图 一、基本介绍 二、代码实现 一、基本介绍 ??图是一种非线性的数据结构,一般用它来反映数据所对应元素之间的几何关系和拓扑关系。图中包括可以具有零个或者多个相邻元素的节点(顶点),以及两个节点之间的连线——边,共同构成
-
数据可视化之matplotlib实战:plt.axvspan() axhspan()函数 绘制
数据可视化之matplotlib实战:plt.axvspan() axhspan()函数 绘制水平or垂直参考区域 import matplotlib.pyplot as pltimport numpy as npx = np.linspace(0.05,10,1000)y = np.sin(x)plt.plot(x,y,ls=-.,lw=2,c=c,label=plot figure)plt.legend()plt.axvspan(
-
java基础学习笔记7
java基础学习笔记7 网络 Ip地址 四个字节 每个字节最大到255 提供独一无二的IP地址 TCP 可靠,传输慢 UDP 不可靠,传输慢。QQ聊天 Socket 网络编程也叫Socket编程 端口号 计算机每个进程都有一个或多个端口 TCP Socket模型 代码实现: 半双工聊天: talkserve
-
Javaweb学习05JavaBean和MVC三层架构
Javaweb学习05JavaBean和MVC三层架构 JavaBean 实体类 必须有一个无參构造 属性必须私有化 必须有对应的set/get方法 一般用来和数据库的字段做映射 ORM(object-relational mapping) ORM: 对象关系映射 表 - 类 字段 - 属性 行记录 - 对象 bodyh1Javabean/h1%-
-
数据可视化之matplotlib实战:plt.legend()函数 标示不同图形的
数据可视化之matplotlib实战:plt.legend()函数 标示不同图形的文本标签图例 import matplotlib.pyplot as pltimport numpy as npx = np.linspace(0.05,10,1000)y = np.sin(x)plt.plot(x,y,ls=-.,lw=2,c=c,label=plot figure)plt.legend()plt.show()
-
《Linux性能优化实战》笔记(22)—— 网络丢包问题分析
《Linux性能优化实战》笔记(22)—— 网络丢包问题分析 所谓丢包,是指在网络数据的收发过程中,由于种种原因,数据包还没传输到应用程序中,就被丢弃了。这些被丢弃包的数量,除以总的传输包数,也就是我们常说的丢包率。丢包率是网络性能中最核心的指标之
-
数据可视化之matplotlib实战:plt.barh()函数 绘制条形图
数据可视化之matplotlib实战:plt.barh()函数 绘制条形图 import matplotlib as mplimport matplotlib.pyplot as plt# 防止乱码mpl.rcParams[font.sans-serif] = [SimHei]mpl.rcParams[axes.unicode_minus] = False# 生产数据x = [1,2,3,4,5,6,7,8]y = [3,1,4
-
玩转java多线程 之多线程基础 线程状态 及线程停止实战
玩转java多线程 之多线程基础 线程状态 及线程停止实战 从网上先找了下,觉得这两张图比较好 比较清楚的看到线程的5大状态 新生状态: Thread t = new Thread() 线程对象一旦创建,就进入到新生状态 就绪状态 当调用start()方法,线程立即进入就绪状态的,但