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?
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]);
}
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;
}
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]
for(int i=1;i<str.length;i++){
String arr[] = str[i].split(":");
map.put(arr[0], arr[1]);
}
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.
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.
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
}
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.
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/