首页 > 解决方案 > 如何使用高效的 Java 流将 Map 转换为 CSV?

问题描述

我想将 a 转换Map<String, List<String>>为 CSV,其中每个 List 应生成一个 csv 行。

Map<String, List<String>> map;

String csv = map.stream()
   .map(entry -> entry.values().stream().collect(Collectors.joining(";")))
   .collect(Collectors.joining("\n"));

问题:对于大型列表,这将String在列表与 连接的中间步骤中产生许多对象;

问题:是否可以重写以上内容以将结果收集为单个高效StringBuilder

或者我应该在这里放弃该stream方法并使用一个简单的for-each循环,手动附加结果StringBuilder.append()

标签: javajava-stream

解决方案


问题:对于大型列表,这将在列表与 ; 连接的中间步骤中生成许多 String 对象。

不过,这不是问题。一些“在上下文中”运行并几乎立即有效地变成垃圾的小对象是“快速垃圾”,通常几乎没有与之相关的成本。鉴于此 CSV 可能会指向磁盘或网络连接,因此此类事物对性能的任何影响都相形见绌。

单效StringBuilder

... 是的。你正在使用它:Collectors.joining.

你是如何确定你的发现的,因为它们听起来很可疑。具体来说:

许多字符串对象

你的分析器告诉你了吗?您是否正确识别问题?在你的代码运行之前,你大量的 String 对象(Map<String, List<String>>毕竟 - 很多字符串!)

高效的

CSV 格式强烈表明此 CSV 数据正在脱离进程,无论是到磁盘还是通过网络。一般来说,传输这些数据的效率低下实际上比过程中的低效率影响大几千倍,所以如果你得出这个结论是因为你的代码运行速度比你想要的慢,那么你正在寻找错误的东西. 而是查看通过网络管道或磁盘发送这些内容的代码。您没有粘贴此代码,但是有很多很多方法可以使它变得非常低效,所以大概这是您的实际问题,如果您发布这个 SO 问题是因为您的代码运行速度比您认为的要慢。


推荐阅读