You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java创建Student类读取成绩文件遇问题,求正确实现方案

解决读取文件创建Student对象时的成绩提取问题

我看了你遇到的问题,核心是在读取文件内容时,Scanner方法混用导致的读取错位,再加上几个细节问题,才没法正确创建Student对象。咱们一步步拆解问题并解决:

先说说你现有代码里的几个关键问题

  • Scanner读取方法混用导致错位:第一行是考试数量3,你用input.nextLine()读取时,第一次循环会读这行,但后续用nextInt()读完数字后,并不会消耗换行符,下一次nextLine()会读到空字符串,直接导致姓名读取错误。
  • 成绩数组引用重复:你只创建了一个grade数组,每次循环都往里面覆盖新成绩,最后所有Student对象都会指向同一个数组,所有学生的成绩都会变成最后一组的值。
  • 提前关闭Scanner:你在while循环内部调用了input.close(),第一次循环结束后Scanner就被关闭,后续根本没法继续读取其他学生的数据。
  • 数组打印方式错误:直接调用grade.toString()或打印getStudentGrades(),输出的是数组的哈希值,不是实际成绩内容,得用Arrays.toString()才能看到数组里的具体数值。

修正后的完整代码

主程序读取文件的代码

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class StudentReader {
    public static void main(String[] args) {
        try {
            File file = new File("info1.txt");
            Scanner input = new Scanner(file);
            
            // 读取第一行的考试数量,然后消耗掉换行符
            int examCount = input.nextInt();
            input.nextLine();

            // 用动态列表存储学生,避免提前固定数组长度的麻烦
            List<Student> studentList = new ArrayList<>();

            while (input.hasNextLine()) {
                // 读取整行学生数据
                String studentLine = input.nextLine();
                // 按空格分割成姓名+成绩的字符串数组
                String[] parts = studentLine.split(" ");
                
                String studentName = parts[0];
                int[] grades = new int[examCount];
                // 把分割后的字符串转成int类型的成绩
                for (int i = 0; i < examCount; i++) {
                    grades[i] = Integer.parseInt(parts[i + 1]);
                }

                // 创建Student对象并加入列表
                Student student = new Student(studentName, grades);
                studentList.add(student);

                // 打印测试:用Arrays.toString()输出数组内容
                System.out.println(student.getName() + " " + Arrays.toString(student.getStudentGrades()));
            }

            input.close();

            // 如果需要转成数组的话
            Student[] students = studentList.toArray(new Student[0]);

        } catch (FileNotFoundException e) {
            System.out.println("找不到目标文件:" + e.getMessage());
        }
    }
}

规范后的Student类

public class Student {
    // 遵循Java命名规范:变量名小驼峰,成员变量封装为private
    private String name;
    private int[] studentGrades;

    public Student(String name, int[] studentGrades) {
        this.name = name;
        // 克隆数组,避免外部修改影响对象内部数据
        this.studentGrades = studentGrades.clone();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int[] getStudentGrades() {
        // 返回数组副本,防止外部直接修改内部数组
        return studentGrades.clone();
    }

    public void setStudentGrades(int[] studentGrades) {
        this.studentGrades = studentGrades.clone();
    }
}

关键改动说明

  1. 正确处理Scanner换行:用nextInt()读取考试数量后,调用input.nextLine()消耗掉该行的换行符,确保后续nextLine()能正确读取每个学生的完整行数据。
  2. 按行分割处理数据:把每个学生的行用split(" ")拆成字符串数组,直接提取姓名和成绩,完全避免了Scanner方法混用的错位问题。
  3. 每个学生独立的成绩数组:每次循环都新建一个grades数组,保证每个Student对象拥有自己独立的成绩数据,不会互相覆盖。
  4. 数组安全封装:在Student类的构造方法和getter里克隆数组,避免外部代码直接修改对象内部的成绩数组,保证数据安全性。
  5. 动态存储学生:用ArrayList代替固定长度的数组,不用提前预估学生数量,更灵活健壮。

内容的提问来源于stack exchange,提问作者Alihan Aydın

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:03:33