15

HI I have a csv called test.csv . I am trying to read the csv line by line and convert the values into a hash key value pairs . Here is the 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);
 }
}

The csv file is as follows :-

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"

When I run this code I get this error :-

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

Can anyone please help me to fix the code and find out the error in my program ?

8 Answers 8

14

Using FasterXML's CSV package: 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;
}
Sign up to request clarification or add additional context in comments.

3 Comments

I think this a better solution that OpenCSV
Using version 2.13.1 and getting java.lang.NoSuchMethodError: 'com.fasterxml.jackson.core.io.ContentReference com.fasterxml.jackson.dataformat.csv.CsvFactory._createContentReference(java.lang.Object)' at com.fasterxml.jackson.dataformat.csv.CsvFactory.createParser(CsvFactory.java:300) at com.fasterxml.jackson.dataformat.csv.CsvFactory.createParser(CsvFactory.java:16) at com.fasterxml.jackson.databind.ObjectReader.createParser(ObjectReader.java:1027) at com.fasterxml.jackson.databind.ObjectReader.readValues(ObjectReader.java:1953)
Cannot construct instance of java.util.LinkedHashMap (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value
11

In your String when you split it on first time only contains arr[0] as 1 nothing in arr[1] so it will cause an Exception

If you does not need the 1,2, etc.. You can look the following code:

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

Comments

3

The problem is that when you split your str, the first element in each line is alone (i.e 1 and 2). So arr only contains ["1"], and hence arr[1] doesn't exists.

I.e for the example input :

1,"testCaseName":"ACLTest"

split by , => str contains {1, testCaseName:ACLTest}
split by : at the first iteration => arr contains {1}

Example :

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

Output :

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


To fix your code (if you don't want to use a CSV parser), make your loop starting at 1 :

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


Another problem is that the HashMap use the hashCode of the keys to store the (key, value) pairs.

So when insering "testCaseName":"ACLTest" and "testCaseName":"DCLAddTest", the first value will be erased and replace by the second one :

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

Output :

{testCaseName=DCLAddTest}

So you have to fix that too.

Comments

0

Look at the output of the call String arr[] = str[i].split(":"); arr[1] does not exists for the first element in your CSV file which happens to be 1, 2... You can start the loop with int i=0 to fix this issue.

Comments

0

String.split is rubbish for parsing CSV. Either use the Guava Splitter or a proper CSV parser. You can parse CSV into beans using the Jackson CSV mapper like this:

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

more info at http://demeranville.com/how-not-to-parse-csv-using-java/

Comments

0

Beside the problem you have with the first number which its not a pair and its causing the Exception, you will not want to use Hashmap, since hashmap use a unique key, so line 2 will replace values from line 1.

You should use a MultiMap, or a List of pairs in this case.

Comments

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

}

Comments

-1

using openCSV would be one way to do it

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

the jar is available here

1 Comment

How do I get the values in a Hash?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.