将CSV值转换为JAVA中的HashMap键值对

时间:2013-11-19 09:59:55

标签: java csv hashmap

我有一个名为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)

任何人都可以帮我修复代码并找出程序中的错误吗?

8 个答案:

答案 0 :(得分:10)

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

答案 1 :(得分:8)

在你的字符串中,当你第一次拆分时只在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]);
        }

答案 2 :(得分:1)

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

即示例输入:

1,"testCaseName":"ACLTest"

, =&gt;分割str包含{1, testCaseName:ACLTest}
在第一次迭代时按:分割=&gt; 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}

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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/

的更多信息

答案 5 :(得分:0)

除了第一个数字的问题,它不是一对而导致异常,你不会想要使用Hashmap,因为hashmap使用唯一的键,所以第2行将替换第1行的值。

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

答案 6 :(得分:0)

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

}

答案 7 :(得分:-1)

使用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();
        }
    }
}

jar可用here