必须用ArrayList<Student>封装学生对象而非字符串,重写equals()和hashCode()以支持正确删除,查数据优先用Stream或HashMap索引,增删改后需序列化或导出CSV持久化。

用 ArrayList 存学生对象,别直接存字符串
学生信息不是单个值,而是姓名、学号、年龄等组合。硬塞进 String 或 String[] 会导致后续改查混乱,比如想按学号找人,得遍历每个字符串再切分——错一次就全崩。
必须封装成类:
class Student {
private String id;
private String name;
private int age;
// 构造、getter、setter 真实开发里不能少
}然后用 ArrayList<Student> 存。泛型写死类型,编译期就能拦住误加非学生对象的错误。
remove() 删不掉?检查你传的是对象还是索引
ArrayList.remove() 有两个重载:一个删指定索引(int),一个删首次匹配的对象(Object)。如果传了个 Student 实例进去却没删掉,大概率是没重写 equals() 和 hashCode() —— 默认比较内存地址,两个内容一样的 Student 对象也不相等。
实操建议:
- 删指定位置:用
list.remove(2),确保索引在0到list.size()-1范围内,越界抛IndexOutOfBoundsException - 删指定学生:先重写
Student.equals()(只比id就够),再调list.remove(student) - 批量删:别边遍历边
remove(),用Iterator.remove()或removeIf()
查学生时别用 for (int i = 0; i 硬循环
能用增强 for 或 stream 就别手写索引循环。前者少写错边界,后者语义清晰:
// 找学号为 "2023001" 的学生
Student target = list.stream()
.filter(s -> "2023001".equals(s.getId()))
.findFirst()
.orElse(null);注意 stream 在数据量大时有开销,纯内存小系统(几百条)没问题;如果频繁查且数据稳定,考虑用 HashMap<String, Student> 按学号做索引,get() 是 O(1)。
增/改后不保存,重启程序数据就丢
ArrayList 是内存集合,JVM 停了数据全清零。学生管理系统至少得落盘:
- 简单演示:用
ObjectOutputStream序列化到文件,但要求Student实现Serializable,且文件格式不通用 - 真实点的做法:导出为 CSV,用
BufferedWriter写,每行id,name,age,人眼可读,Excel 能打开 - 千万别把路径写死成
"C:\data\students.txt",用getClass().getResource("/data/").getPath()或配置文件读取
IOException,别用空 catch 吞掉,至少打日志或提示“保存失败,请检查磁盘空间”。
对象封装和集合操作本身不难,难的是什么时候该用什么结构、改完数据要不要同步到文件、查不到人时返回 null 还是抛异常——这些细节堆起来,才是实际跑得稳的系统。










