如何用Stream API从文件读取数组并填充Student类marks字段?
问题修复与Stream API优化方案
原代码核心问题
- 冗余操作:将文件行转成List再转数组,完全违背Stream API的流式处理思路
- Marks解析逻辑错误:循环内每次重置
c=0,导致只有第一个数字被存入数组 - 性能浪费:重复调用
l.split(" "),多次拆分同一字符串 - 逻辑失效:最终Student对象的marks字段用了固定值
new Integer[]{1,1,1},没有使用解析后的真实数据
优化后的完整代码
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 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) throws IOException { String path1 = "C:\\Users\\Professional\\IdeaProjects\\Lesson\\src\\StreamAPI\\FileStream"; List<Student6> students = Files.lines(Paths.get(path1)) .filter(line -> !line.startsWith("#")) // 跳过注释行 .map(line -> { String[] parts = line.split(" "); // 仅拆分一次,复用结果 int id = Integer.parseInt(parts[0]); String name = parts[1]; String surname = parts[2]; // 简洁解析marks数组 String marksStr = parts[3].replaceAll("[\\[\\]]", ""); Integer[] marks = Arrays.stream(marksStr.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)); } } 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<String>,省去List转数组的冗余步骤,全程流式操作更高效 - 字符串拆分复用:每行仅调用一次
split(" "),将结果存入parts数组复用,避免重复拆分的性能损耗 - Marks解析简化:
- 用
replaceAll("[\\[\\]]", "")移除marks字符串的首尾括号,得到纯数字逗号分隔格式 - 通过
Arrays.stream()将拆分后的字符串转成流,用map(Integer::parseInt)完成类型转换 - 用
toArray(Integer[]::new)直接生成符合要求的Integer数组,完美匹配Student类字段
- 用
- 修复逻辑错误:真正将解析后的marks传入Student构造器,解决原代码固定值填充的问题
内容的提问来源于stack exchange,提问作者R Zav
相关产品推荐
相关产品推荐

