如何使用Java 8 Stream将csv转换为地图

时间:2016-04-07 17:09:34

标签: java csv lambda java-8 java-stream

我试图创建一个简单的解析工具,转换两列CSV文件并将其放入地图中。

public Map<String, String> getMapFromCSV(final String filePath) throws IOException {
    return Files.lines(Paths.get(filePath))
                .map(line -> line.split(","))
                .collect(Collectors.toMap(line -> line[0], line -> line[1]));
}

正如您所看到的,我创建了一个字符串流,分隔逗号上的每一行并将其转换为字符串数组,最后将键映射到索引0,将值映射到索引1。

@Test
public void testGetMapFromCSV() throws IOException{
    actual = util.getMapFromCSV(filePath).get("AL");
    expected = "ALABAMA";

    assertEquals(expected, actual);
}

出于某种原因,当我运行此测试时,实际值为null。我排除了无效的filePath,因为它在另一个单元测试中正常工作,并且键值存在于CSV中。我现在已经盯着它看了几个小时,想想也许有人可以指出我的错误。

此外,我对Java 8还不熟悉,所以如果有人知道更好/更清晰的写作方式,我会很感激反馈。

3 个答案:

答案 0 :(得分:2)

好的,我添加了lines.close()并删除了csv中的任何空格,它都有效!奇怪的是,考虑到csv在我的其他方法中被解析得很好。这是它的样子:

public static Map<String, String> getMapFromCSV(final String filePath) throws IOException{

        Stream<String> lines = Files.lines(Paths.get(filePath));
        Map<String, String> resultMap = 
                lines.map(line -> line.split(","))
                     .collect(Collectors.toMap(line -> line[0], line -> line[1]));

        lines.close();

        return resultMap;
    }

答案 1 :(得分:1)

使用 AutoCloseable 尝试使用资源

作为 commented by fge,使用 try-with-resources 使这更容易。

这是来自 your Answer 的代码,但使用 try-with-resources 自动关闭 Stream 也是 AutoCloseable。并添加了一些用于呼吸空间的空格字符。

public static Map<String, String> getMapFromCSV(final String filePath) throws IOException{

    try (
        Stream < String > lines = Files.lines( Paths.get( filePath ) );
    )
    {
        Map < String , String > resultMap = 
                lines.map( 
                         line -> line.split( "," ) 
                     )
                     .collect(
                         Collectors.toMap( line -> line[0] , line -> line[1] )
                     );
        return resultMap;
    }
    // The `Stream` named `lines` is automatically closed at this point by the try-with-resources.
}

当 try-with-resources 的 {…} 块结束时,在 try 中打开的任何资源都会自动关闭,顺序与打开顺序相反。无论控制流在完成时优雅地离开块,还是由于异常或 return(如您的代码所示)而突然离开块,都是如此。请参阅关于此问题的讨论,Try-with-resources and return statements in java

答案 2 :(得分:0)

以一种可能更容易阅读的形式 - 使用 mapping

public static Map<String, String> getMapFromCSV(final String filePath) throws IOException {
  try(Stream<String> lines = Files.lines(Paths.get(filePath))) {
      return lines.collect(
        mapping(s -> s.split(","), toMap(k -> k[0], v -> v[1])));
  }
}