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

如何使用Java Stream从文件读取数组并填充Student类字段?

Java Stream解析文件生成Student对象(修复marks数组解析问题)

问题场景

需要解析文本文件,将每行数据映射为Student对象,文件每行格式为ID Name Surname [成绩列表],原代码在提取成绩数组时无法正确填充字段。

文件内容示例:

# Name Surname Marks
1 Mike Scott [4,5,5]
2 Joe Jones [1,2,3]

原代码问题分析

  1. 不必要地将Files.lines返回的Stream转成List再转数组,Stream可直接链式操作
  2. 处理成绩字符串时,循环内重置计数器c,导致只有第一个成绩被赋值,且最终返回固定数组{1,1,1},完全未使用解析出的成绩
  3. 多次调用split(" ")重复拆分字符串,效率低下

修正后的实现方案

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Student6 {
    private int id;
    private String name;
    private String surname;
    private Integer[] marks;

    // 构造方法(修正字段命名符合Java规范)
    public Student6(int id, String name, String surname, Integer[] marks) {
        this.id = id;
        this.name = name;
        this.surname = surname;
        this.marks = marks;
    }

    // 重写toString方便调试验证
    @Override
    public String toString() {
        return "Student6{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", surname='" + surname + '\'' +
                ", marks=" + Arrays.toString(marks) +
                '}';
    }

    public static void main(String[] args) {
        String filePath = "C:\\Users\\Professional\\IdeaProjects\\Lesson\\src\\StreamAPI\\FileStream";

        try {
            List<Student6> students = Files.lines(Paths.get(filePath))
                    // 跳过注释行和空行
                    .filter(line -> !line.isBlank() && !line.startsWith("#"))
                    .map(line -> {
                        // 拆分每行,split(" ",4)确保成绩部分的字符串完整提取
                        String[] parts = line.split(" ", 4);
                        int id = Integer.parseInt(parts[0]);
                        String name = parts[1];
                        String surname = parts[2];
                        String marksStr = parts[3];

                        // 解析成绩字符串:去掉首尾[],按逗号分割后转成Integer数组
                        Integer[] marks = Arrays.stream(marksStr.substring(1, marksStr.length() - 1).split(","))
                                .map(String::trim)
                                .map(Integer::parseInt)
                                .toArray(Integer[]::new);

                        return new Student6(id, name, surname, marks);
                    })
                    .collect(Collectors.toList());

            // 打印结果验证
            students.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

关键优化点

  • 直接使用Files.lines的Stream链式操作,避免不必要的集合转数组
  • 用split(" ", 4)拆分每行,确保成绩段字符串完整提取(即使成绩包含空格也不受影响)
  • 用Stream处理成绩字符串,通过substring移除首尾[],再转成Integer数组,逻辑简洁不易出错
  • 添加文件读取异常处理,增强代码健壮性
  • 修正字段命名为Java规范的小写开头,提升代码可读性

内容的提问来源于stack exchange,提问作者R Zav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:05:33