如何使用 opencsv 将 csv 解析为按列分组的 hashmap

How to parse the csv to hashmap grouping by column using opencsv

我正在尝试使用 CSVREADER 将 col1 值哈希映射到 csv 文件中的 col2 值。但是我找不到这样做的逻辑。

我想通过 CSVReader 读取 CSV、循环数据线并使用 arraylist 和 hashmap 键和值 (arraylist) 来实现。我不想硬编码..

我做了一些事情,直到下面。无法继续进行。请帮忙..

        CSVReader csvReader = new CSVReader(new FileReader(fileName),',','"',1);
        Map<String, List<String>> tableandcols = new HashMap<String, List<String>>();
        ArrayList<String> tablenames = new ArrayList<>();
        ArrayList<String> colnames = new ArrayList<>();
        while((row = csvReader.readNext()) != null) {
            tablenames.add(row[0]);
            colnames.add(row[1]);
            }

input data: 
State,City,Country
NJ,Trenton,US
NJ,Newark,US
NC,Cary,US
NC,Charlotte,US
GA,Atlanta,US

I want the data to be in hashmap as following
[<NJ,[Trenton,Newark]>
<NC,[Cary,Charlotte]>
<GA,[Atlanta]>]

您可以试试下面的代码:

    try
    {
      CSVReader csvReader = new CSVReader(new FileReader(fileName),',','"',1);
      Map<String, List<String>> tableandcols = new HashMap<String, List<String>>();
      while((row = csvReader.readNext()) != null) 
      {
        // If map contains state already, add the city to the values list
        if(tableandcols.containsKey(row[0]))
         { 
           tableandcols.get(row[0]).add(row[1);
         }
         // if map doesn't have this state as key, insert a key and value
         else {
           List<String> cities = new ArrayList<>();
           cities.add(row[1]);
           tableandcols.put(row[0], cities);
         }
      }
     } 
     catch(Exception e){
      // log exception
     }

或者,您也可以使用 HeaderColumnNameTranslateMappingStrategy 将列值映射到 java bean。遍历 java beans 列表并根据州聚合城市。

您可以简单地使用 java-8 流方法来完成,使用 readAll 读取 List<String[]>

中的完整文件

Reads the entire file into a List with each element being a String[] of tokens. Since the current implementation returns a LinkedList, you are strongly discouraged from using index-based access methods to get at items in the list. Instead, iterate over the list.

如果您想使用 headers 跳过第一行,请使用 skip(1),然后使用 Collectors.groupingBy 根据 State

对元素进行分组
Map<String, List<String>> res = arr.stream().skip(1)
            .collect(Collectors.groupingBy(str -> str[0], Collectors.mapping(str -> str[1], Collectors.toList())));

或使用 map.compute

的简单 for 循环
List<String[]> arr = csvReader.readAll();

Map<String, List<String>> tableandcols = new HashMap<String, List<String>>();

for(String[] array : arr) {
    tableandcols.compute(array[0], (key,val)->val==null ? new ArrayList<>() : val).add(array[1]);
}