
本文讲解如何使用java动态收集多个学生信息(id、姓名、学院、专业),支持用户通过输入“yes/no”决定是否继续添加,并在结束录入后统一打印所有已保存的数据。
本文讲解如何使用java动态收集多个学生信息(id、姓名、学院、专业),支持用户通过输入“yes/no”决定是否继续添加,并在结束录入后统一打印所有已保存的数据。
在开发学生信息管理系统时,一个常见需求是:允许用户反复录入多条学生记录,直到明确输入“no”才停止,并最终一次性展示全部数据。初学者常因变量作用域、循环嵌套和数组索引管理不当导致逻辑错误——例如重复覆盖同一行数据、无法正确终止循环,或仅打印最后一条记录。下面将从问题诊断出发,提供结构清晰、健壮可复用的解决方案。
? 核心问题分析
原代码存在三个关键缺陷:
- row 变量在每次内层 while(in.hasNext()) 循环中被重置为 0,导致新数据始终写入第 0 行;
- case "yes" 中未递增 row,造成后续录入覆盖前一条记录;
- case "no" 仅打印 students[row][...](即最后一行),未遍历所有已存数据;
- switch 缺少 break 导致“fall-through”,输入 "no" 时仍会执行 "yes" 分支逻辑。
✅ 正确实现方案
import java.util.Scanner;
public class StudentInfoManager {
public static void main(String[] args) {
// 使用二维数组存储最多50名学生,每名学生4项信息
String[][] students = new String[50][4];
Scanner in = new Scanner(System.in);
int row = 0; // ? 全局计数器:记录当前待写入的行号(从0开始)
System.out.println("=== 学生信息录入系统 ===");
while (true) {
System.out.println("\n--- 录入第 " + (row + 1) + " 位学生 ---");
System.out.print("请输入学号: ");
students[row][0] = in.nextLine().trim();
System.out.print("请输入姓名: ");
students[row][1] = in.nextLine().trim();
System.out.print("请输入学院: ");
students[row][2] = in.nextLine().trim();
System.out.print("请输入专业: ");
students[row][3] = in.nextLine().trim();
System.out.println("✅ 记录已保存!");
// 询问是否继续
String decision;
do {
System.out.print("是否继续添加?(YES/NO): ");
decision = in.nextLine().trim().toLowerCase();
if (!decision.equals("yes") && !decision.equals("no")) {
System.out.println("⚠️ 请输入 'YES' 或 'NO'(不区分大小写)");
}
} while (!decision.equals("yes") && !decision.equals("no"));
if (decision.equals("no")) {
break; // ? 明确退出主循环
}
row++; // ? 仅当用户选择"yes"时递增,准备下一行
if (row >= students.length) {
System.out.println("⚠️ 已达最大容量(50人),停止录入。");
break;
}
}
// 打印全部学生信息
System.out.println("\n" + "=".repeat(60));
System.out.println("? 全部学生信息汇总(共 " + (row + 1) + " 条):");
System.out.printf("%-12s %-20s %-15s %-15s%n",
"学号", "姓名", "学院", "专业");
System.out.println("-".repeat(60));
for (int i = 0; i <= row; i++) {
// 防止空指针:确保该行数据非null(理论上不会发生,但属良好实践)
if (students[i][0] != null) {
System.out.printf("%-12s %-20s %-15s %-15s%n",
students[i][0],
students[i][1] != null ? students[i][1].toUpperCase() : "",
students[i][2] != null ? students[i][2].toUpperCase() : "",
students[i][3] != null ? students[i][3].toUpperCase() : "");
}
}
System.out.println("=".repeat(60));
in.close(); // ? 关闭Scanner,避免资源泄漏
}
}⚠️ 关键注意事项
- row 必须声明在 while 外部:保证其值在多次循环中持续累加;
- break 不可省略:switch 中每个 case 后必须显式 break,否则会顺序执行后续分支;
- 输入校验增强鲁棒性:使用 toLowerCase() 和 trim() 统一处理大小写与空格;
- 边界防护:检查 row >= students.length 避免数组越界;
- 资源管理:调用 in.close() 释放 Scanner 占用的系统资源;
- 格式化输出:使用 printf 实现对齐排版,提升可读性。
? 进阶建议(面向工程实践)
若项目规模扩大,推荐将 String[][] 替换为面向对象设计:
class Student {
private String id, name, college, program;
// 构造函数、getter/setter...
}
List<Student> studentList = new ArrayList<>();这能显著提升代码可维护性、类型安全性与扩展能力(如后续增加成绩、联系方式等字段)。
立即学习“Java免费学习笔记(深入)”;
通过以上重构,您将获得一个逻辑清晰、容错性强、符合Java编程规范的学生信息批量录入工具。核心思想在于:用单一状态变量(row)驱动数据存储位置,用明确的循环控制流替代嵌套判断,再以线性遍历完成结果聚合——这是处理类似“重复输入→集中输出”场景的经典范式。










