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

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

问题描述

我有一个Student类,其中marks字段为数组类型,需要从文件中读取数据来填充该类的所有字段,且要求通过Java Stream实现。目前编写的代码存在问题,希望了解更简便的Stream实现方式,或是如何修复现有代码。

现有代码
class Lesson_Stream6 {
//        # Name Surname Marks
//        1 Mike Scott [4,5,5]
//        2 Joe Jones [1,2,3]
//        3 Ann Fleming [3,3,3]
    public static void main(String[] args) {
String path1 = "C:\\Users\\Professional\\IdeaProjects\\Lesson\\src\\StreamAPI\\FileStream";
        List<String> fileLineName = new ArrayList<>();
        List<String> fileLineNameSurname = new ArrayList<>();
        List<String> stream1 = Files.lines(Paths.get(path1)).toList();
        String[] arr =  new String[stream1.size()];
        for (int i = 0; i < stream1.size(); i++) {
            arr[i] = stream1.get(i);
        }
        List<String>NameSurname = Stream.of(arr)
                .filter( line -> !line.startsWith("#"))
                .map( l -> l.split(" ")[1] + l.split(" ")[2])
                .collect(Collectors.toList());
        List<Student6>student4s = Stream.of(arr)
                .filter( line -> !line.startsWith("#"))
                .map( l -> {
                    String s = l.split(" ")[3];
                    String[] chars = s.split("");
                    Integer[] integers = new Integer[3];

                    for (int i = 0; i < chars.length; i++) {
                        if (chars[i].matches("[0-9]")) {
                            int c = 0;
                            integers[c++] = Integer.parseInt(chars[i]);
                        }
                    }
                   out.println(Arrays.toString(integers));
                    return new Student6(Integer.parseInt(l.split(" ")[0]), l.split(" ")[1], l.split(" ")[2],
                            new Integer[]{1, 1, 1});

                })
                .collect(Collectors.toList());

        out.println(student4s.get(1).Name);
    }
}
class Student6 {

    int ID;
    String Name;
    String Surname;
    Integer [] marks;

    public Student6(int ID, String name, String surname, Integer[] marks) {
        this.ID = ID;
        Name = name;
        Surname = surname;
        this.marks = marks;
    }
}
现有代码问题分析
  1. 冗余操作:将Files.lines返回的Stream转成List再转数组完全多余,直接使用原始Stream即可。
  2. Marks处理逻辑错误:循环中int c = 0;会每次重置索引,导致只有integers[0]能被赋值;且通过拆分字符数组提取数字的方式效率低、逻辑繁琐。
  3. 重复拆分字符串:多次调用l.split(" ")会重复创建数组,浪费性能。
  4. 无效赋值:最终返回Student6时硬编码了new Integer[]{1,1,1},完全没用到处理后的integers数组。
  5. 异常未处理:Files.lines会抛出IO异常,原代码未做捕获处理。
优化后的Stream实现代码
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Lesson_Stream6 {
    // 文件内容示例:
    // # Name Surname Marks
    // 1 Mike Scott [4,5,5]
    // 2 Joe Jones [1,2,3]
    // 3 Ann Fleming [3,3,3]
    public static void main(String[] args) {
        String path1 = "C:\\Users\\Professional\\IdeaProjects\\Lesson\\src\\StreamAPI\\FileStream";
        
        try {
            List<Student6> students = Files.lines(Paths.get(path1))
                    // 跳过注释行
                    .filter(line -> !line.startsWith("#"))
                    // 单行转换为Student对象,仅拆分一次字符串
                    .map(line -> {
                        String[] parts = line.split(" ");
                        int id = Integer.parseInt(parts[0]);
                        String name = parts[1];
                        String surname = parts[2];
                        
                        // 提取并转换marks数组:去除[]符号后按逗号拆分,转成Integer数组
                        String marksRaw = parts[3].replaceAll("[\\[\\]]", "");
                        Integer[] marks = Arrays.stream(marksRaw.split(","))
                                .map(Integer::parseInt)
                                .toArray(Integer[]::new);
                        
                        return new Student6(id, name, surname, marks);
                    })
                    .collect(Collectors.toList());
            
            // 测试输出
            System.out.println(students.get(1).Name);
            System.out.println(Arrays.toString(students.get(1).marks));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Student6 {
    int ID;
    String Name;
    String Surname;
    Integer[] marks;

    public Student6(int ID, String name, String surname, Integer[] marks) {
        this.ID = ID;
        Name = name;
        Surname = surname;
        this.marks = marks;
    }
}
优化点说明
  • 直接使用Files.lines生成的Stream,省略冗余的List、数组转换步骤。
  • 每行仅执行一次split(" "),避免重复创建字符串数组。
  • 用正则表达式快速去除marks字段的[]符号,再通过Stream将字符串集合转为Integer数组,逻辑简洁高效。
  • 增加IO异常捕获,保证代码健壮性。
  • 删除原代码中无实际作用的中间集合。

内容的提问来源于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 12:43:11