解决方案
你可以通过在进入循环之前完全消耗第一行来实现你想要的,只需调用
in.nextLine();
之前和第一行被消耗。
拆分
但是,我会以不同的方式处理这个问题,逐行解析,然后在 | 上拆分,这样可以更轻松地处理每行给出的数据。
in.nextLine();
while (in.hasNextLine()) {
String line = in.nextLine();
String[] data = line.split("\\|");
String name = data[0];
int[] testResults = new int[data.length - 1];
for (int i = 0; i < testResults.length; i++) {
testResults[i] = Integer.parseInt(data[i + 1]);
}
...
}
正确的 OOP
理想情况下,您应该添加一些 OOP,创建一个类 Student,其中包含类似的字段
public class Student {
private final String name;
private final int[] testResults;
// constructor, getter, ...
}
然后给它一个parseLine 方法,例如:
public static Student parseLine(String line) {
String[] data = line.split("\\|");
String name = data[0];
int[] testResults = new int[data.length - 1];
for (int i = 0; i < testResults.length; i++) {
testResults[i] = Integer.parseInt(data[i + 1]);
}
return new Student(name, testResults);
}
然后您的解析大大简化为:
List<Student> students = new ArrayList<>();
in.nextLine();
while (in.hasNextLine()) {
students.add(Student.parseLine(in.nextLine());
}
流和 NIO
或者,如果您喜欢流,只需使用 NIO 读取文件:
List<Student> students = Files.lines(Path.of("myFile.txt"))
.skip(1)
.map(Student::parseLine)
.collect(Collectors.toList());
非常清晰、紧凑且易读。
平均分
我的目标是能够获得每个学生的平均考试成绩,以及每次考试的平均成绩(列)和总体平均成绩。
使用正确的 OOP 结构,如图所示,这相当简单。首先,一个学生的平均分,在Student类中添加一个方法即可:
public double getAverageScore() {
double total = 0.0;
for (int testResult : testResults) {
total += testResult;
}
return total / testResults.length;
}
替代流解决方案:
return IntStream.of(testResults).average().orElseThrow();
接下来,每列的平均分:
public static double averageTestScore(List<Student> students, int testId) {
double total = 0.0;
for (Student student : students) {
total += student.getTestScores()[testId];
}
return total / students.size();
}
以及流式解决方案:
return students.stream()
.mapToInt(student -> student.getTestScores[testId])
.average().orElseThrow();
最后是总体平均分,可以通过取每个学生的平均分来计算:
public static double averageTestScore(List<Student> students) {
double total = 0.0;
for (Student student : students) {
total += student.getAverageScore();
}
return total / students.size();
}
和流变体:
return students.stream()
.mapToDouble(Student::getAverageScore)
.average().orElseThrow();