
本文讲解如何使用arraylist动态存储用户多次输入的计算结果(如 grade × units),并安全高效地求和,避免数组大小限制问题,适合零基础学生快速上手。
本文讲解如何使用arraylist动态存储用户多次输入的计算结果(如 grade × units),并安全高效地求和,避免数组大小限制问题,适合零基础学生快速上手。
在你的QPI(Quality Point Index)程序中,核心需求是:反复接收多门课程的“质量点”(grade)和“学分单位”(units),计算每门课的加权分(grade × units),并将所有加权分累积保存,最后求总和用于QPI计算。当前代码的问题在于:每次循环都用同一个变量 newgrade 覆盖前一次结果,导致历史数据丢失;且 qpi = newgrade / total 仅使用了最后一次输入的 total,逻辑错误(QPI应为 所有加权分之和 ÷ 所有学分单位之和)。
✅ 正确做法是:用 ArrayList
以下是优化后的完整可运行代码(含详细注释):
import java.util.ArrayList;
import java.util.Scanner;
public class QPI {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 用于动态存储每门课的加权分(grade × units)
ArrayList<Integer> weightedGrades = new ArrayList<>();
// 累计所有课程的学分单位总数
int totalUnits = 0;
System.out.println("=== QPI Calculator ===");
System.out.println("Enter your quality point equivalent and units for each subject.");
int response;
do {
System.out.print("Enter quality point (e.g., 4, 3.5, 3...): ");
double grade = scanner.nextDouble(); // 注意:grade可能是小数,用double更准确
// 成绩等级映射(简化版,实际可封装为方法)
if (grade == 4.0) System.out.println("Grade: A");
else if (grade == 3.5) System.out.println("Grade: B+");
else if (grade == 3.0) System.out.println("Grade: B");
else if (grade == 2.5) System.out.println("Grade: C+");
else if (grade == 2.0) System.out.println("Grade: C");
else if (grade == 1.0) System.out.println("Grade: D");
else if (grade == 0.0) System.out.println("Grade: F");
else System.out.println("Grade: Unknown");
System.out.print("Enter total units for this subject: ");
int units = scanner.nextInt();
// 计算该科加权分(grade × units),转为int(或保留double精度)
int weightedGrade = (int) Math.round(grade * units); // 四舍五入取整
weightedGrades.add(weightedGrade);
totalUnits += units;
System.out.println("✓ Weighted score added: " + weightedGrade);
System.out.println("Current total units: " + totalUnits);
System.out.println("Type 1 to add another subject, 2 to calculate QPI:");
response = scanner.nextInt();
} while (response == 1);
// ✅ 安全求和:遍历ArrayList累加所有加权分
int sumWeightedGrades = 0;
for (int score : weightedGrades) {
sumWeightedGrades += score;
}
// 计算QPI:总加权分 ÷ 总学分(注意:需转为double避免整数除法截断)
double qpi = (totalUnits != 0)
? (double) sumWeightedGrades / totalUnits
: 0.0;
System.out.println("\n=== Results ===");
System.out.println("Total weighted scores: " + sumWeightedGrades);
System.out.println("Total units: " + totalUnits);
System.out.printf("Your QPI is: %.2f%n", qpi); // 保留两位小数输出
}
}? 关键改进说明:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
立即学习“Java免费学习笔记(深入)”;
-
动态存储:ArrayList
weightedGrades 替代单一变量 newgrade,自动扩容,无容量焦虑; - 正确累加:独立维护 totalUnits,确保分母为所有课程学分之和;
- 类型安全:grade 改用 double 接收(因3.5等小数无法用 int 存储),避免输入异常;
- 防错处理:检查 totalUnits != 0 避免除零错误;
- 可读性增强:添加清晰提示、格式化输出(printf 控制小数位)。
? 进阶提示(可选):若想用现代Java特性简化求和,可在JDK 8+中使用Stream:
int sum = weightedGrades.stream().mapToInt(Integer::intValue).sum();
但对初学者,传统for循环更直观易懂,推荐优先掌握基础写法。
通过以上结构化设计,你的程序不仅能正确求和,还具备良好的扩展性与健壮性——这才是编程思维的核心。

















