要求:使用List集合存储自定义的对象集合,并熟练使用List集合的中常用方法实现相关的操作。
Java环境:jdk 17
IDE :Idea 2021.1.3
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;都无所谓,因为虚拟机都已经退出了。
}
关于其中的代码功能,我在注释中已经写的够清楚了,请仔细阅读。
答案是肯定的。有很多可以继续优化的地方。
先来看一下这个方法的代码:
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,完美的解决了这个问题。
主要都在一个类中,定义全局变量比用形参传值要方便而且还会减少一定的内存开销。
其实在很多时候,不管我们用的是Jdbc还是一些封装好的框架例如:Mybatis,在数据库中建好表,在访问这些数据中也是用一个映射类来做映射。然后用 list
将数据保存在列表中,将其返回给前端。
在此例子中,我自己默认将这里的学号作为一个类似于数据库中的主键,不可重复性,是唯一值来处理。
自己只看标题,慢慢的将代码写出来,中间可能会遇到各种各样的问题,最好自己先思考一段时间慢慢的将其解决。更多的百度带来的只会让自己思维更加固定与死板。对自己写代码的能力不会提高,反而会下降。自己独立完成这个小练习后,对于后续的Java学习,特别是与数据库连接,老一套的增删改查有一定的思维帮助。
程序中可能还有一些问题,或者是一些代码的冗余性,请多见谅。