Search code examples
javalambdahashmap

How can I parse List<List> into ArrayList<HashMap> through lambda expression?


Maybe it's quite a stupid question but I cant find any solution for it. I am new to lambda and I am trying to use it to parse a list <List> into an ArrayList <HashMap>.

Initially I parse a data set from csv file, and I turn each row of them into a List, and add them into the List <'List'> I stated above. Since I have to filter them after this, I would like to change the each row of them into a HashMap<columnName, columnValue>, but when I try to do it, it returns nothing.

Here is my code:

// import data from csv file
private static List<List> readWholeFile(BufferedReader br) throws IOException {
    List<List> rows = new ArrayList<>();
    String line = br.readLine();

    try {
        if (line != null) {
            String[] test = line.split(",");
            List<String> row = Arrays.asList((String[]) line.split(","));
            rows.add(row);
            return readWholeFile(br);
        }
    } catch (NullPointerException ex) {
        ex.printStackTrace();
    } finally {
        return rows;
    }
}

//parse List<List> into ArrayList<HashMap>
private static ArrayList<HashMap> putRowIntoMap(List<List> rows, List<String> columns) {
    ArrayList<HashMap> itemMap = new ArrayList<>();
    List<HashMap> test = new ArrayList<>();
    HashMap<String, String> eleMap = new HashMap<>();
    rows.stream().map(row -> (row.stream().map(ele -> eleMap.put(keys.get(row.indexOf(ele)), (String) ele))))
            .collect(Collectors.toCollection(ArrayList::new));
    itemMap.add(eleMap);
    System.out.println(eleMap);  //output: {}

    return itemMap;
}

Solution

    1. Read the input file into List<List<String>> using NIO Files.lines returning lines of the text file as Stream<String>
    public static List<List<String>> readFile(String filename) throws IOException {
        return Files.lines(Paths.get(filename)) // Stream<String>
            .map(line -> Arrays.asList(line.split(","))) // Stream<List<String>>
            .collect(Collectors.toList());               // List<List<String>>
    }
    
    1. Convert the list of List<String> into map, assuming that the columnNames have the same indexes as the lists inside rows and all column names are different.
    public static List<Map<String, String>> intoMap(List<List<String>> rows, List<String> columnNames) {
        return rows.stream() // Stream<List<String>>
            .map(row -> IntStream.range(0, row.size()) // IntStream
                .boxed() // Stream<Integer>
                .collect(Collectors.toMap(
                    i -> columnNames.get(i), // key: columnName
                    i -> row.get(i)          // value
                    // ,(r1, r2) -> r1,       // placeholder for merge function
                    // LinkedHashMap::new    // supplier of LinkedHashMap
                )) // Map<String, String>
            ) // List<Map<String, String>>
            .collect(Collectors.toList());
    }
    

    By default, Collectors.toMap returns a HashMap implementation which is not ordered, so it could make sense to use LinkedHashMap maintaining insertion order (if needed, two commented lines in the toMap should be uncommented).