【问题标题】:Convert CSV values to a HashMap key value pairs in JAVA将 CSV 值转换为 JAVA 中的 HashMap 键值对
【发布时间】:2013-12-02 19:39:21
【问题描述】:

您好,我有一个名为 test.csv 的 csv。我正在尝试逐行读取 csv 并将值转换为哈希键值对。 这是代码:-

public class Example {
public static void main(String[] args) throws ParseException, IOException {
    // TODO Auto-generated method stub

    BufferedReader br = new BufferedReader(new FileReader("test.csv"));
    String line =  null;
    HashMap<String,String> map = new HashMap<String, String>();

    while((line=br.readLine())!=null){
        String str[] = line.split(",");
        for(int i=0;i<str.length;i++){
            String arr[] = str[i].split(":");
            map.put(arr[0], arr[1]);
        }
    }
    System.out.println(map);
 }
}

csv 文件如下:-

1,"testCaseName":"ACLTest","group":"All_Int","projectType":"GEN","vtName":"NEW_VT","status":"ACTIVE","canOrder":"Yes","expectedResult":"duplicateacltrue"
2,"testCaseName":"DCLAddTest","group":"India_Int","projectType":"GEN_NEW","vtName":"OLD_VT","status":"ACTIVE","canOrder":"Yes","expectedResult":"invalidfeaturesacltrue"

当我运行这段代码时,我得到了这个错误:-

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
    Example.main(Example.java:33)

谁能帮我修复代码并找出程序中的错误?

【问题讨论】:

    标签: java csv hashmap


    【解决方案1】:

    使用 FasterXML 的 CSV 包: https://github.com/FasterXML/jackson-dataformats-text/tree/master/csv

    public static List<Map<String, String>> read(File file) throws JsonProcessingException, IOException {
        List<Map<String, String>> response = new LinkedList<Map<String, String>>();
        CsvMapper mapper = new CsvMapper();
        CsvSchema schema = CsvSchema.emptySchema().withHeader();
        MappingIterator<Map<String, String>> iterator = mapper.reader(Map.class)
                .with(schema)
                .readValues(file);
        while (iterator.hasNext()) {
            response.add(iterator.next());
        }
        return response;
    }
    

    【讨论】:

    • 我认为这是一个比 OpenCSV 更好的解决方案
    【解决方案2】:

    第一次拆分时,在您的字符串中仅包含 arr[0]1,而 arr[1] 中没有任何内容,因此会导致异常

    如果你不需要1,2等。你可以看下面的代码:

            String str[] = line.split(",");
            for(int i=1;i<str.length;i++){
                String arr[] = str[i].split(":");
                map.put(arr[0], arr[1]);
            }
    

    【讨论】:

      【解决方案3】:

      问题是当你split你的str时,每行的第一个元素是单独的(即1和2)。所以arr 只包含["1"],因此arr[1] 不存在。

      即示例输入:

      1,"testCaseName":"ACLTest"
      

      , 拆分 => str 包含{1, testCaseName:ACLTest}
      在第一次迭代时由 : 拆分 => arr 包含 {1}

      例子:

      String s = "1,testCaseName:ACLTest";
      String str[] = s.split(",");
      System.out.println(Arrays.toString(str));
      for(String p : str){
          String arr[] = p.split(":");
          System.out.println(Arrays.toString(arr));
      }
      

      输出:

      [1, testCaseName:ACLTest]
      [1] //<- here arr[1] doesn't exists, you only have arr[0] and hence the ArrayIndexOutOfBoundsException when trying to access arr[1]
      [testCaseName, ACLTest]
      


      要修复您的代码(如果您不想使用 CSV 解析器),请让您的循环从 1 开始:
      for(int i=1;i<str.length;i++){
            String arr[] = str[i].split(":");
            map.put(arr[0], arr[1]);
      }
      


      另一个问题是HashMap 使用键的hashCode 来存储(键,值)对。

      所以当插入"testCaseName":"ACLTest""testCaseName":"DCLAddTest" 时,第一个值将被删除并替换为第二个值:

      Map<String, String> map = new HashMap<>();
      map.put("testCaseName","ACLTest");
      map.put("testCaseName","DCLAddTest");
      System.out.println(map);
      

      输出:

      {testCaseName=DCLAddTest}
      

      所以你也必须解决这个问题。

      【讨论】:

        【解决方案4】:

        查看调用的输出 String arr[] = str[i].split(":"); CSV 文件中的第一个元素(恰好是 1、2)不存在 arr[1]... 您可以使用 int i=0 启动循环来解决此问题。

        【讨论】:

          【解决方案5】:

          String.split 对于解析 CSV 来说是垃圾。使用 Guava Splitter 或适当的 CSV 解析器。您可以使用 Jackson CSV 映射器将 CSV 解析为 bean,如下所示:

          public class CSVPerson{
            public String firstname;
            public String lastname;
            //etc
          }
          
          CsvMapper mapper = new CsvMapper();
          CsvSchema schema = CsvSchema.emptySchema().withHeader().withColumnSeparator(delimiter);
          MappingIterator<CSVPerson> it = = mapper.reader(CSVPerson).with(schema).readValues(input);
          while (it.hasNext()){
            CSVPerson row = it.next();
          }
          

          更多信息http://demeranville.com/how-not-to-parse-csv-using-java/

          【讨论】:

            【解决方案6】:

            除了第一个数字不是一对并且导致异常的问题之外,您不会想要使用 Hashmap,因为 hashmap 使用唯一键,因此第 2 行将替换第 1 行中的值。

            在这种情况下,您应该使用 MultiMap 或对列表。

            【讨论】:

              【解决方案7】:
              import java.io.BufferedReader;
              import java.io.FileReader;
              import java.io.IOException;
              import java.util.*;
              public class Example {
              
              
                  public static void main(String[] args) {
              
                      String csvFile = "test.csv";
                      String line = "";
                      String cvsSplitBy = ",";
                      HashMap<String, String> list = new HashMap<>();
                      try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
              
                          while ((line = br.readLine()) != null) {
              
                              // use comma as separator
                              String[] country = line.split(cvsSplitBy);
              
                              //System.out.println(country[0] +"  "  + country[1]);
                              list.put(country[0], country[1]);
                          }
              
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                      System.out.println(list);
              
                  }
                 // enter code here
              
              }
              

              【讨论】:

                【解决方案8】:

                使用 openCSV 是一种方法

                import java.io.FileNotFoundException;
                import java.io.FileReader;
                import java.io.IOException;
                
                import au.com.bytecode.opencsv.CSVReader;
                
                public class CsvFileReader {
                    public static void main(String[] args) {
                
                        try {
                            System.out.println("\n**** readLineByLineExample ****");
                            String csvFilename = "C:/Users/hussain.a/Desktop/sample.csv";
                            CSVReader csvReader = new CSVReader(new FileReader(csvFilename));
                            String[] col = null;
                            while ((col = csvReader.readNext()) != null) 
                            {
                                System.out.println(col[0] );
                                //System.out.println(col[0]);
                            }
                            csvReader.close();
                        }
                        catch(ArrayIndexOutOfBoundsException ae)
                        {
                            System.out.println(ae+" : error here");
                        }catch (FileNotFoundException e) 
                        {
                            System.out.println("asd");
                            e.printStackTrace();
                        } catch (IOException e) {
                            System.out.println("");
                            e.printStackTrace();
                        }
                    }
                }
                

                罐子可用here

                【讨论】:

                • 如何获取哈希值?
                猜你喜欢
                • 2020-08-14
                • 1970-01-01
                • 2016-07-02
                • 1970-01-01
                • 2021-03-30
                • 2015-04-23
                • 1970-01-01
                • 2016-05-29
                • 2021-12-15
                相关资源
                最近更新 更多