Matt Matt - 1 month ago 18
Java Question

Getting an OutOfBounds exception after reading a csv file into an array

I'm writing a program that takes a csv file, and reads each of the lines into an array of USCrimeClass objects that have their own field. I want to see if the arrays are being made correctly by printing one of them out, but I am getting an OutOfBounds exception.

import java.io.*;
import java.util.*;
public class USCrimeClass
{
public int year;
public int population;
public int violentCrime;
public double violentCrimeRate;
public int manslaughter;
public double manslaughterRate;
public int rape;
public double rapeRate;
public int robbery;
public double robberyRate;
public int assault;
public double assaultRate;
public int propertyCrime;
public double propertyCrimeRate;
public int burglary;
public double burglaryRate;
public int larcenyTheft;
public double larcenyTheftRate;
public int vehicleTheft;
public double vehicleTheftRate;

public USCrimeClass(String line)
{
String[]split=line.split(",");
year=Integer.parseInt(split[0]);
population=Integer.parseInt(split[1]);
violentCrime=Integer.parseInt(split[2]);
violentCrimeRate=Double.parseDouble(split[3]);
manslaughter=Integer.parseInt(split[4]);
manslaughterRate=Double.parseDouble(split[5]);
rape=Integer.parseInt(split[6]);
rapeRate=Double.parseDouble(split[7]);
robbery=Integer.parseInt(split[8]);
robberyRate=Double.parseDouble(split[9]);
assault=Integer.parseInt(split[10]);
assaultRate=Double.parseDouble(split[11]);
propertyCrime=Integer.parseInt(split[12]);
propertyCrimeRate=Double.parseDouble(split[13]);
burglary=Integer.parseInt(split[14]);
burglaryRate=Double.parseDouble(split[15]);
larcenyTheft=Integer.parseInt(split[16]);
larcenyTheftRate=Double.parseDouble(split[17]);
vehicleTheft=Integer.parseInt(split[18]);
vehicleTheftRate=Double.parseDouble(split[19]);
}

public static void main(String[] args)
{
Scanner read = null;
{
try
{
read=new Scanner(new File("C:\\Crime.csv"));
}
catch(FileNotFoundException e)
{
System.out.println("The file can't be opened");
System.exit(0);
}



String[] lines = null;

read.nextLine();
while(read.hasNextLine())
{
lines=read.nextLine().split(",");
}

USCrimeClass[] CrimeYear=new USCrimeClass[lines.length];

for(int i=0;i<lines.length;i++)
{
CrimeYear[i]=new USCrimeClass(lines[i]);
}
read.close();

System.out.println(CrimeYear[0]);
}
}
}


Here is what the csv file should look like

1994,260327173,1130,3.7,3890,39.5,...
1995,250692382,2478,21.5,2230,28.6,...
1996,230492492,4092,22.8,3202,39.4...


And here is the error message

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at USCrimeClass.<init>(USCrimeClass.java:30)
at USCrimeClass.main(USCrimeClass.java:84)

Answer

Regarding this code:

while(read.hasNextLine())
{
    lines = read.nextLine().split(",");
}

what you are doing here is reading the file line by line, but you are always overwriting lines with the currently read line. In the end lines will only contain the split contents of the last line and not all lines in the csv file.

Add each read line to a list and then this should work:

List<String> lines = new ArrayList<>();

read.nextLine();
while(read.hasNextLine())
{
    lines.add(read.nextLine());
}

USCrimeClass[] CrimeYear = new USCrimeClass[lines.size()];

for(int i=0;i<lines.size();i++)
{
    CrimeYear[i]=new USCrimeClass(lines.get(i));
}
read.close();

In case you don't want to buffer all the read lines, you can also directly create the corresponding objects:

List<USCrimeClass> crimeClasses = new ArrayList<>();
read.nextLine();
while(read.hasNextLine())
{
    crimeClasses.add(new USCrimeClass(read.nextLine()));
}

read.close();

System.out.println(crimeClasses.get(0));

BTW: I'd also recommend putting the read.close() into a finally { ... } block.