有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何使用Java8流将csv转换为地图

我试图创建一个简单的解析util,它转换一个两列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。我排除了无效的文件路径,因为它在另一个单元测试中运行良好,并且键值出现在CSV中。我已经盯着它看了几个小时了,我想也许有人会指出我的错误

另外,我对Java8还相当陌生,因此如果有人知道更好/更干净的编写方法,我将非常感谢您的反馈


共 (3) 个答案

  1. # 1 楼答案

    使用AutoCloseable尝试使用资源

    commented by fge一样,使用try-with-resources使这更容易

    下面是来自your Answer的代码,但是使用try with resources自动关闭一个^{},它也是^{}。并为呼吸室添加了一些空格字符

    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. # 2 楼答案

    以更容易阅读的形式–使用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])));
      }
    }
    
  3. # 3 楼答案

    好的,我添加了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;
        }