数组存成绩易现索引越界和类型混用;Scanner录入时nextInt()后需nextLine()清回车;学生应建模为对象而非仅用数组或集合存储。

用数组存学生成绩时,索引越界和类型混用最常见
直接用 int[] 或 double[] 存成绩看似简单,但实际容易出错:比如把学生姓名塞进 int[],或遍历时写成 i 导致 ArrayIndexOutOfBoundsException。更隐蔽的问题是,数组长度固定,新增学生就得手动扩容——这不是“管理”,只是硬编码。
实操建议:
- 只用数组存纯数值型成绩(如
double[] scores),且初始化时明确长度:double[] scores = new double[50]; - 配套用一个
int studentCount记录当前有效人数,避免遍历整个数组 - 如果要同时存姓名、学号、成绩,别硬塞进多个平行数组(易错位),改用对象封装
用 ArrayList\ 封装数据比“三个数组”靠谱得多
很多初学者用 String[] names、int[] ids、double[] scores 三组数组并行管理,结果增删一个学生时三组不同步,查成绩时下标对不上。
正确做法是定义 Student 类,再用 ArrayList 统一操作:
立即学习“Java免费学习笔记(深入)”;
class Student {
String name;
int id;
double score;
Student(String name, int id, double score) {
this.name = name;
this.id = id;
this.score = score;
}
}
这样增删查改都基于单个对象,不会错位。注意:ArrayList 默认初始容量为 10,频繁 add 不会崩溃,但大量数据时可预设容量提升性能:new ArrayList(100)。
按成绩排序或查找时,别手写冒泡,用 Collections.sort()
想找出最高分、前五名、或按分数升序打印名单?手写排序不仅慢还易错。Java 提供了稳定、可复用的方案。
关键点:
- 让
Student实现Comparable,重写compareTo()按score比较 - 或者用
Collections.sort(students, Comparator.comparingDouble(s -> s.score)) - 查找特定学号?别循环遍历,先确保
Student正确重写了equals()和hashCode(),再用students.indexOf(target)或流式查找:students.stream().filter(s -> s.id == 1001).findFirst()
从控制台输入到 List 的过程中,Scanner.nextLine() 吃掉回车是高频坑
用 Scanner 录入学生信息时,如果先调 nextInt() 读学号,再调 nextLine() 读姓名,第二行姓名会变成空字符串——因为 nextInt() 不吞回车,nextLine() 立刻读到换行符就返回了。
解决办法只有两个:
- 统一用
nextLine(),然后对数字字段手动Integer.parseInt() - 在
nextInt()后加一句scanner.nextLine()清掉残留回车
另外,Scanner 不是线程安全的,单线程命令行程序没问题;但若将来扩展成多线程录入,得换 BufferedReader 或加锁。
真正麻烦的不是存数据,而是“学生”这个概念没被当成一个整体来建模——数组只管容器,集合只管结构,而业务逻辑(比如“及格线变动”“按班级分组”)必须落在对象行为里。这点在后续加功能时会立刻暴露出来。










