如何基于Student对象数组计算各实验成绩的最值与平均值?
嘿,这个问题其实挺典型的——当数据是按「学生行」存储,但我们需要按「实验列」做统计时,核心就是把遍历视角转过来就行!我给你一步步拆解怎么做:
先明确前提(基于你提到的类结构)
首先假设你的Student类和Util类大概是这样的(如果实际结构有小差异,调整getter即可):
public class Student { private int studentId; private int[] scores; // 存储5次实验的成绩 // 构造器、getter方法 public int getStudentId() { return studentId; } public int[] getScores() { return scores; } } // 提供学生数组的工具类 public class Util { public static Student[] getStudents() { // 返回包含15个Student对象的数组 } }
核心思路:按实验序号遍历,收集所有学生的对应成绩
我们不用去“转置”整个数组,而是直接针对每个实验(比如第1到第5次),遍历所有学生拿到他们在这个实验上的分数,再计算最低、最高、平均分。具体步骤如下:
步骤1:初始化统计容器
先拿到学生数组,确定实验次数(这里是5次,不过用第一个学生的成绩数组长度更灵活),然后准备存储每个实验统计结果的数组:
Student[] students = Util.getStudents(); int totalExperiments = students[0].getScores().length; // 这里会得到5 // 初始化三个数组,分别存每个实验的最低分、最高分、平均分 int[] experimentMins = new int[totalExperiments]; int[] experimentMaxs = new int[totalExperiments]; double[] experimentAvgs = new double[totalExperiments];
步骤2:遍历每个实验,计算统计值
对每个实验索引(从0到4),遍历所有学生的对应成绩,逐步更新最低分、最高分,累加总分后计算平均分:
for (int expIdx = 0; expIdx < totalExperiments; expIdx++) { // 用第一个学生的当前实验成绩初始化最低、最高和总分 int currentMin = students[0].getScores()[expIdx]; int currentMax = students[0].getScores()[expIdx]; int totalScore = currentMin; // 从第二个学生开始遍历,更新统计值 for (int studentIdx = 1; studentIdx < students.length; studentIdx++) { int score = students[studentIdx].getScores()[expIdx]; if (score < currentMin) currentMin = score; if (score > currentMax) currentMax = score; totalScore += score; } // 计算平均分(转成double避免整数除法的精度丢失) double avgScore = (double) totalScore / students.length; // 把结果存入对应数组 experimentMins[expIdx] = currentMin; experimentMaxs[expIdx] = currentMax; experimentAvgs[expIdx] = avgScore; }
步骤3:输出或使用统计结果
现在你可以把结果打印出来,或者用在其他业务逻辑里:
// 循环打印每个实验的统计数据 for (int i = 0; i < totalExperiments; i++) { System.out.printf("实验%d:最低分%d,最高分%d,平均分%.2f%n", i + 1, // 实验序号从1开始显示 experimentMins[i], experimentMaxs[i], experimentAvgs[i]); }
额外优化建议
- 增加容错校验:如果担心学生数组为空,或者某个学生的成绩数量和其他不一致,可以加一些校验逻辑:
if (students == null || students.length == 0) { throw new IllegalArgumentException("学生数组不能为空"); } for (Student student : students) { if (student.getScores().length != totalExperiments) { throw new IllegalArgumentException( String.format("学生%d的成绩数量不匹配,应为%d次", student.getStudentId(), totalExperiments) ); } } - 用自定义类封装统计结果:如果想让代码更清晰,可以定义一个
ExperimentStats类来封装每个实验的三个统计值,这样后续使用结果时更直观:
然后用class ExperimentStats { private int minScore; private int maxScore; private double avgScore; public ExperimentStats(int min, int max, double avg) { this.minScore = min; this.maxScore = max; this.avgScore = avg; } // getter方法和toString方法 @Override public String toString() { return String.format("最低分%d,最高分%d,平均分%.2f", minScore, maxScore, avgScore); } }ExperimentStats[] statsArray = new ExperimentStats[totalExperiments];来存储结果,代码可读性会提升很多。
内容的提问来源于stack exchange,提问作者Alan Navai
相关产品推荐
相关产品推荐

