web-dev-qa-db-fra.com

Conversion de valeurs CSV en paires de valeurs de clé HashMap en JAVA

HI j'ai un csv appelé test.csv. J'essaie de lire ligne par ligne le csv et de convertir les valeurs en une paire de clés de hachage . Voici le code: -

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

Le fichier csv est comme suit: - 

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"

Lorsque je lance ce code, j'obtiens cette erreur: -

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

Quelqu'un peut-il s'il vous plaît m'aider à corriger le code et à trouver l'erreur dans mon programme?

8
Newbie

Dans votre chaîne, lorsque vous l'avez divisée pour la première fois, ne contient que arr[0] en tant que 1 rien dans arr[1], de sorte que cela provoquera une exception.

Si vous n'avez pas besoin du 1,2, etc. Vous pouvez regarder le code suivant:

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

Utilisation du package CSV de FasterXML: 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;
}
9
Kechit Goyal

Le problème est que lorsque vous split votre str, le premier élément de chaque ligne est seul (c'est-à-dire 1 et 2). Donc, arr ne contient que ["1"], et par conséquent, arr[1] n'existe pas.

I.e pour l'exemple d'entrée:

1,"testCaseName":"ACLTest"

divisé par , => str contient {1, testCaseName:ACLTest}
divisé par : à la première itération => arr contient {1}

Exemple :

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

Sortie:

[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]


Pour réparer votre code (si vous ne voulez pas utiliser un analyseur CSV), faites votre boucle à partir de 1:

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


Un autre problème est que la HashMap utilise la hashCode des clés pour stocker les paires (clé, valeur).

Ainsi, lors de l'insertion de "testCaseName":"ACLTest" et "testCaseName":"DCLAddTest", la première valeur sera effacée et remplacée par la seconde:

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

Sortie:

{testCaseName=DCLAddTest}

Donc, vous devez résoudre ce problème aussi.

1
Alexis C.

En plus du problème que vous avez avec le premier nombre qui n'est pas une paire et qui cause l'exception, vous ne voudrez pas utiliser Hashmap, puisque hashmap utilise une clé unique, la ligne 2 remplacera donc les valeurs de la ligne 1.

Vous devez utiliser un MultiMap ou une liste de paires dans ce cas.

0
cri_sys
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

}
0
dimuthu93

Regardez le résultat de l'appel String arr[] = str[i].split(":"); Arr [1] n'existe pas pour le premier élément de votre fichier CSV qui se trouve être 1, 2 ... Vous pouvez démarrer la boucle avec int i = 0 à résoudre ce problème.

0
Marek Puchalski

String.split est un déchet pour l'analyse de fichiers CSV. Utilisez soit le séparateur de goyave ou un analyseur CSV approprié. Vous pouvez analyser le CSV en beans en utilisant le mappeur Jackson CSV comme ceci:

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

plus d'infos sur http://demeranville.com/how-not-to-parse-csv-using-Java/

0
tom