简体   繁体   中英

How to convert csv to a map using Java 8 Stream

I'm trying to create a simple parsing util that converts a two-column CSV file and put it into a map.

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]));
}

As you can see, I'm creating a stream of strings, delimiting each line on a comma and transforming it into a string array, and finally mapping key to index 0 and value to index 1.

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

    assertEquals(expected, actual);
}

For some reason, when I run this test, the actual value is null. I ruled out invalid filePath because it's working fine in another unit test, and the key value is present in the CSV. I've been staring at it for a few hours now, figured maybe someone here could point out my error.

Also, I'm fairly new to Java 8, so if anyone knows a better/cleaner way of writing this, I'd appreciate the feedback.

Ok, I added lines.close() and removed any whitespace from the csv and it works! Strange, considering the csv got parsed fine in my other method. Here's what it looks like:

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;
    }

Try-with-resources with AutoCloseable

As commented by fge , using try-with-resources makes this easier.

Here is the code from your Answer but using try-with-resources to automatically close a Stream that is also AutoCloseable . And some added SPACE characters for breathing room.

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.
}

When the {…} block of the try-with-resources ends, any resources opened in the try are automatically closed, in reverse order of their opening. This is true whether flow-of-control leaves the block gracefully upon completion, or abruptly due to an exception or a return (as seen in your code). See discussion on this Question, Try-with-resources and return statements in java .

in a form that might be easier to read – with 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])));
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM