[英]How to convert a CSV file to List<Map<String,String>>
我有一个 CSV 文件,第一行有一个标题。 我想将它转换为List<Map<String, String>>
,其中List<Map<String, String>>
中的每个Map<String, String>
代表文件中的一条记录。 映射的键是标题,值是字段的实际值。 到目前为止我所拥有的:
BufferedReader br = <handle to file>;
// Get the headers to build the map.
String[] headers = br.lines().limit(1).collect(Collectors.toArray(size -> new String[size]));
Stream<String> recordStream = br.lines().skip(1);
我可以对recordStream
执行哪些进一步的操作,以便我可以将其转换为List<Map<String, String>>
?
示例 CSV 文件是:
header1,header2,header3 ---- Header line
field11,field12,field13 ----> need to transform to Map where entry would be like header1:field11 header2:field12 and so on.
field21,field22,field23
field31,field32,field33
最后,需要将所有这些 Map 收集到一个列表中。
以下将起作用。 标题行是通过直接在BufferedReader
上调用readLine
并围绕,
拆分来检索的。 然后,读取文件的其余部分:每一行都围绕 分割,
并映射到具有相应标题的Map
。
try (BufferedReader br = new BufferedReader(...)) {
String[] headers = br.readLine().split(",");
List<Map<String, String>> records =
br.lines().map(s -> s.split(","))
.map(t -> IntStream.range(0, t.length)
.boxed()
.collect(toMap(i -> headers[i], i -> t[i])))
.collect(toList());
System.out.println(headers);
System.out.println(records);
};
这里非常重要的一点是, BufferedReader.lines()
在被调用时不会返回一个新的Stream
:我们不能在读取标题后跳过 1 行,因为读取器已经前进到下一行。
作为旁注,我使用了try-with-resources
构造,以便可以正确关闭BufferedReader
。
我知道这是一个老问题,但我遇到了同样的问题,并创建了Tagir Valeev提到的Commons CSV解决方案的快速示例:
Reader in = new FileReader("path/to/file.csv");
Iterable<CSVRecord> records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in);
List<Map> listOfMaps = new ArrayList<>();
for (CSVRecord record : records) {
listOfMaps.add(record.toMap());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.