0

I am new to Java and practice parsing csv file. I do understand what does IndexOutOfBound means, but I don't understand why my parsed data cannot do like all the tutorials I've visited such as https://examples.javacodegeeks.com/java-csv-parsing-example/

I can only read the first column, which is data[0]. There must be something wrong with my parsing method, but I cannot figure it out. Any help or hint is hight appreciated.

my data file looks like this:

  [0],    [1], [2],    [3]  ,    [4]    ,   [5]   ,  [6] ,   [7]  ,  [8] , [9]
class, gender, age, bodyType, profession, pregnant, isYou ,species, isPet, role
scenario:green,   ,         ,           ,         ,        ,      ,      ,
person, female, 24, average , doctor    , FALSE   ,        ,      ,      , passenger
animal, male  ,  4,         ,           , FALSE   ,        , dog  , TRUE , pedestrian
  .
  .

I tried to parse like this:

ArrayList<String> csvContents = new ArrayList<String>();    

try (BufferedReader csvReader = new BufferedReader(new FileReader(csvFile));) {
        String headerLine = csvReader.readLine(); //get rid of header

        while ((line = csvReader.readLine()) != null) { 
            csvContents.add(line);// add the line to the ArrayList      
        }

for (String csvLine : csvContents) {

            // split by comma and remove redundant spaces
            String[] data = csvLine.split("\\s*,\\s*"); 
            System.out.println(data[1]);// IndexOutOfBound

            Character character = null;
            String clazz = data[0].toLowerCase();// cannot use word "class" as a variable

            Profession professionEnum = Profession.valueOf(data[4].toUpperCase());  
            Gender genderEnum = Gender.valueOf(data[1].toUpperCase());
            BodyType bodyTypeEnum =BodyType.valueOf(data[3].toUpperCase());

            if (clazz.startsWith("scenario")) { 
                scenario = new Scenario();
                scenario.setLegalCrossing(clazz.endsWith("green"));
                continue;
            } else if ("person".equals(clazz)) {

                person = new Person(Integer.parseInt(data[2]), professionEnum ,genderEnum , bodyTypeEnum , Boolean.parseBoolean(data[5]));
                person.setAsYou(Boolean.parseBoolean(data[6]));
            } else if ("animal".equals(clazz)) {
                animal = new Animal(Integer.parseInt(data[2]) , genderEnum , bodyTypeEnum, data[7]);
                animal.setIsPet(Boolean.parseBoolean(data[8]));
            }
} catch (someException e) {
      e.printStackTrace();
}

EDIT

print out csvLine before split:

scenario:green,,,,,,,,,
person,female,24,average,doctor,false,false,,,passenger
person,male,40,overweight,unknown,false,false,,,passenger
person,female,2,average,,false,false,,,passenger
person,male,82,average,,false,false,,,pedestrian
person,female,32,average,ceo,true,false,,,pedestrian
person,male,7,athletic,,false,false,,,pedestrian
animal,male,4,,,false,false,dog,true,pedestrian
scenario:red,,,,,,,,,
7
  • 2
    you will be a lot better off using a proper csv reader, maybe opencsv.sourceforge.net Commented Jun 11, 2020 at 6:40
  • Thanks, I've found this, but I am trying not to use the third party library. @ScaryWombat Commented Jun 11, 2020 at 6:42
  • 2
    Just do a simple split using comma String[] data = csvLine.split(","); and then check the length of your array Commented Jun 11, 2020 at 6:44
  • 1
    Use a debugger. Check the line (or print it out) before you split it. I suspect you have an empty line at the start/end somewhere (or a line without ","). Commented Jun 11, 2020 at 6:51
  • 1
    Print out cvsLine before the split. Commented Jun 11, 2020 at 7:05

3 Answers 3

1

enter image description here

After spliting, the data just have one element, so that when you access data[1], then you get exception. Solution: try with another regex like "," only.

Ps: your csv is malformed at

scenario:green, , , , , , , , Try to put one more ","

Sign up to request clarification or add additional context in comments.

1 Comment

I can access the first column if I loop through the data array.
1

you need to fill comlete data for all cells in a row.

For eg. first line in your csv, contains only 1 cell having value scenario:green which is data[0].

If you fill in data for all other cells in your csv, your will start receiving data[1], data[2], data[3]....

5 Comments

Is there a specific way to do this?
there are two ways to make sure that your data element has size 10 with all values. First is to Make sure you fill all cells in csv. No cell should be blank. . Second option is to use the split method as like this String[] data = csvLine.split("\\s*,\\s*", -1);
Thank you, sir. I've fixed the IndexOutOfBoundException, but I am facing another problem with IllegalArgumentException of no enum constant. I've referred to this post: stackoverflow.com/questions/32068129/… but it doesn't work for mine, still trying.
you are receiving this Exception because Profession.valueOf(data[4].toUpperCase()) has input parameter as empty because data[4] is "" . You need to wrap such lines in try catch blocks.
0

I've figured it out. It's counterintuitive for me, though. I need to specify the length of the data array parsed to put every attribute like this:

ArrayList<String> csvContents = new ArrayList<String>();    

try (BufferedReader csvReader = new BufferedReader(new FileReader(csvFile));) {
    String headerLine = csvReader.readLine(); //get rid of header

    while ((line = csvReader.readLine()) != null) { 
        csvContents.add(line);// add the line to the ArrayList      
    }

for (String csvLine : csvContents) {

        // split by comma and remove redundant spaces
        String[] data = csvLine.split("\\s*,\\s*"); 
        System.out.println(data[1]);// IndexOutOfBound

        Character character = null;
        String clazz = data[0].toLowerCase();// cannot use word "class" as a variable


        if (clazz.startsWith("scenario"&& data.length == 1)) { 
            scenario = new Scenario();
            scenario.setLegalCrossing(clazz.endsWith("green"));
            continue;
        } else if ("person".equals(clazz)&& data.length == 10) {
            Profession professionEnum = Profession.valueOf(data[4].toUpperCase());  
            Gender genderEnum = Gender.valueOf(data[1].toUpperCase());
            BodyType bodyTypeEnum =BodyType.valueOf(data[3].toUpperCase());
            person = new Person(Integer.parseInt(data[2]), professionEnum ,genderEnum , bodyTypeEnum , Boolean.parseBoolean(data[5]));
            person.setAsYou(Boolean.parseBoolean(data[6]));
        } else if ("animal".equals(clazz)) {
            animal = new Animal(Integer.parseInt(data[2]) , genderEnum , bodyTypeEnum, data[7]);
            animal.setIsPet(Boolean.parseBoolean(data[8]));
        }
} catch (someException e) {
  e.printStackTrace();
}

Comments

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.