项目目标:
0、项目实现规划
思维规划
磨刀不误砍柴工,在动手做一个完整的项目之前,我们最应该完成的是对项目的思路整理和功能规划。整体来看,整个项目类似于数据库的增删改查功能。
用户通过控制台操作main,完成增删改查等功能或退出系统。虽然系统用户校验和增删改查在实现方式上是平级,但是从逻辑上,校验是优先于增删改查的,即先登录,再操作。
代码规划
代码规划神似将思维规划实例化,根据思维图的架构,我们很容易将思维图中的每一个功能对应每一个函数。
函数名 | 功能 |
| 退出系统 |
| 登录验证 |
| 添加学生信息 |
| 查询学生信息 |
| 删除学生信息 |
| 修改学生信息 |
== 一切准备就绪!让我们进入代码的世界吧!== |
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