如何用Java 8 Stream替换循环向Writer对象写入字符串?
用Java 8 Stream替换循环实现Writer写入操作
先看你原来的代码结构大概是这样(模拟实现):
public void save(List<ParentType> parents, List<ChildType> children, String filePath) throws IOException { try (FileWriter writer = new FileWriter(filePath)) { writer.write("someStrings\n"); // 遍历ParentType集合写入 for (ParentType p : parents) { writer.write(p.customToString() + "\n"); } // 遍历ChildType集合写入 for (ChildType c : children) { writer.write(c.customToString() + "\n"); } } }
方案1:合并两个集合的Stream统一处理
这种方式把两个集合的流合并,保持和原循环一致的写入顺序,同时用Stream替代循环:
public void saveWithStream(List<ParentType> parents, List<ChildType> children, String filePath) throws IOException { try (FileWriter writer = new FileWriter(filePath)) { writer.write("someStrings\n"); Stream.concat( parents.stream().map(p -> p.customToString() + "\n"), children.stream().map(c -> c.customToString() + "\n") ).forEach(s -> { try { writer.write(s); } catch (IOException e) { // 将受检异常包装为非受检异常,适配Stream的forEach要求 throw new UncheckedIOException(e); } }); } }
方案2:分流转写+辅助方法简化代码
如果想保留原代码中“先处理Parent、再处理Child”的清晰结构,可以分别处理两个Stream,并用辅助方法封装异常逻辑:
public void saveWithStreamSeparate(List<ParentType> parents, List<ChildType> children, String filePath) throws IOException { try (FileWriter writer = new FileWriter(filePath)) { writer.write("someStrings\n"); // 处理ParentType集合 parents.stream() .map(p -> p.customToString() + "\n") .forEach(s -> writeSafely(writer, s)); // 处理ChildType集合 children.stream() .map(c -> c.customToString() + "\n") .forEach(s -> writeSafely(writer, s)); } } // 辅助方法:封装Writer写入的异常处理 private void writeSafely(Writer writer, String content) { try { writer.write(content); } catch (IOException e) { throw new UncheckedIOException(e); } }
关键说明
Writer.write()会抛出受检的IOException,但Stream的forEach不允许抛出受检异常,因此需要将其包装为UncheckedIOException(Java标准库适配类),外层的throws IOException可以正常捕获该异常的根源。- 集合默认的
stream()是顺序流,完全保证写入顺序和原循环一致,不会打乱Parent和Child的写入顺序。 - 不建议用
collect(Collectors.joining())拼接成大字符串后一次性写入——如果集合元素较多,会占用大量内存,逐个写入的方式和原循环的内存效率一致。
内容的提问来源于stack exchange,提问作者user301
相关产品推荐
相关产品推荐

