Noomy
Noomy

Reputation: 17

java.lang.ArrayIndexOutOfBoundsException when trying to read from File

So basically I've been given a question:

Create program that will read content of members.txt file. Members have to be categorized into 3 arrays, one per team. Once all members are processed, output to the terminal information about how many member each team has and what is name of team captain. File values are separated by comma with following schema:

first_name, last_name, team_name, is_captain

And this is the code that I came up with (idk about efficiency because I'm still fairly new):

package ssst.edu.ba;

import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scan = new Scanner("members.txt");
        int rcount = 0, bcount = 0, gcount = 0;
        ArrayList<Student> red = new ArrayList<Student>(5);
        ArrayList<Student> blue = new ArrayList<Student>(5);
        ArrayList<Student> green = new ArrayList<Student>(5);
        String line;
        String rCap = "";
        String bCap = "";
        String gCap = "";

        while ((line = scan.nextLine()) != null) {
            String[] obj = line.split(", ");
            if(obj[2] == "Red") {
                Student a = new Student(obj[0],obj[1],obj[2],Boolean.parseBoolean(obj[3]));
                red.add(a);
                rcount++;
                if(obj[3] == "true") {
                    rCap = obj[0] + obj[1];
                }
            }
            else if (obj[2] == "Blue") {
                Student a = new Student(obj[0],obj[1],obj[2],Boolean.parseBoolean(obj[3]));
                blue.add(a);
                bcount++;
                if(obj[3] == "true") {
                    bCap = obj[0] + obj[1];
                }
            }
            else {
                Student a = new Student(obj[0],obj[1],obj[2],Boolean.parseBoolean(obj[3]));
                green.add(a);
                gcount++;
                if(obj[3] == "true") {
                    gCap = obj[0] + obj[1];
                }
            }
        }
        System.out.println("There are " + rcount + " people on the red team.");
        System.out.println("There are " + bcount + " people on the blue team.");
        System.out.println("There are " + gcount + " people on the green team.");
        System.out.println("The captain for the red team is: " + rCap);
        System.out.println("The captain for the blue team is: " + bCap);
        System.out.println("The captain for the green team is: " + gCap);
    }
}

The class "Student" is simple, it has 3 private String attributes and a private bool value, it also has one constructor with 4 parameters to set the values to ones given in a text document "members.txt"

The text document is looks like this:

Ginny, Gullatt, Blue, false
Tiara, Curd, Red, false
Camie, Poorman, Green, false
Jammie, Hasson, Green, false
Lionel, Hailey, Blue, false
Genevive, Mckell, Red, true
Esteban, Slaubaugh, Blue, false
Elden, Harte, Red, false
Tasia, Rodrigue, Green, false
Nathanial, Dentler, Red, false
Valda, Nicoletti, Blue, false
Kary, Wilkerson, Green, false
Coletta, Akey, Blue, false
Wilmer, Jack, Red, false
Loreta, Agnew, Green, true
Suzy, Cleveland, Red, false
Pasty, Laprade, Blue, false
Candie, Mehaffey, Green, false
Glady, Landman, Blue, true
Tierra, Mckeown, Red, false
Glady, Laprade, Green, false

Problem: I am receiving this exception message

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 1

I don't know if this is tied to the ArrayList or to the String array "obj", and I'm also not sure how to fix it.

Upvotes: 0

Views: 988

Answers (2)

UselesssCat
UselesssCat

Reputation: 2406

To use Scanner with a file, you have to provide the file through the File class, like this:

import java.io.File;
import java.io.FileNotFoundException;

public static void main(String[] args) throws FileNotFoundException {
    Scanner scan = new Scanner(new File("./members.txt"));

    /* ...Some code */
}

Actually you are reading from a stream that only contains the text "members.txt"

Scanner(String source)

Constructs a new Scanner that produces values scanned from the specified string.

So you are using the constructor htat receives a string as parameter not the one that uses a file. Look at https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#Scanner(java.lang.String)

Also you have to use hasNextLine function like:

while (scan.hasNextLine()) {
    line = scan.nextLine();

/* some code */

}

Or you will get the exception java.util.NoSuchElementException

Here is a working version of your program:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public class Main {

    public static void main(String[] args) throws FileNotFoundException {
        Scanner scan = new Scanner(new File("./members.txt"));

        ArrayList<Student> red = new ArrayList<Student> (5);
        ArrayList<Student> blue = new ArrayList<Student> (5);
        ArrayList<Student> green = new ArrayList<Student> (5);

        // we use a map to save the index where is the captain in the array list
        HashMap<String,Integer> captains = new HashMap <String, Integer> ();

        while (scan.hasNextLine()) {
            String[] rawStudent = scan.nextLine().split(", ");
            Student student = new Student(rawStudent);

            ArrayList selectedTeam = red;

            // we select dynamically the list where the student will be added
            switch (student.getTeam()) {
                case "Red": selectedTeam = red; break;
                case "Blue": selectedTeam = blue; break;
                case "Green": selectedTeam = green; break;
            }

            selectedTeam.add(student);

            if (student.isCaptain()) {
                int lastAddedIndex = selectedTeam.size() - 1;

                captains.put(student.getTeam(), lastAddedIndex);
            }
        }

        System.out.println("There are " + red.size() + " people on the red team.");
        System.out.println("There are " + blue.size() + " people on the blue team.");
        System.out.println("There are " + green.size() + " people on the green team.");

        System.out.println("The captain for the red team is: " + red.get(captains.get("Red")).getFullName());
        System.out.println("The captain for the blue team is: " + blue.get(captains.get("Blue")).getFullName());
        System.out.println("The captain for the green team is: " + green.get(captains.get("Green")).getFullName());
    }
}

class Student {
    private String name;
    private String lastName;
    private String team;
    private boolean isCaptain;

    public Student(String p1, String p2, String p3, boolean p4) {
        this.name = p1;
        this.lastName = p2;
        this.team = p3;
        this.isCaptain = p4;
    }

    public Student(String[] list) {
        this(list[0], list[1], list[2], Boolean.parseBoolean(list[3]));
    }

    public String getFullName() {
        return this.name + " " + this.lastName;
    }

    public boolean isCaptain() {
        return this.isCaptain;
    }

    public String getTeam() {
        return this.team;
    }
}

Hope it helps.

Upvotes: 1

Nahid
Nahid

Reputation: 98

I have already made a program similar to this in which i am reading different format of file like CSV EXCEL etc and performing operation on it so you go and check out the code is a industry level code and will give more exposure rather then just to your solution.

https://github.com/NahidAkhter/feeCalculator.git

In short i can give a snippet here below 1) TextTransctionReader.java

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import com.feecalculator.Constant.FILETYPE;
import com.feecalculator.Transaction;


public class TextTransctionReader extends AbstractTransactionReader implements ITransactionManager {


    @Override
    public void readTransaction(File transactionFile) {


        BufferedReader br = null;
        String line = "";
        String cvsSplitBy = ",";

        try {

            br = new BufferedReader(new FileReader(transactionFile));
            while ((line = br.readLine()) != null) {
                String[] transactionAttributes = line.split(cvsSplitBy);
                Transaction transaction = getTransaction(transactionAttributes); 
                saveTransaction(transaction);

            }        
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @Override
    public ITransactionManager readFile(FILETYPE fileType) {
        if(fileType == FILETYPE.TEXT){
            return TrasactionReader.getTrasactionReaderInstance().readTextFile();
        }
        return null;
    }


}

Main class is below:

import java.io.File;

import com.feecalculator.Constant.FILETYPE;
import com.feecalculator.reader.ITransactionManager;
import com.feecalculator.reader.TrasactionReader;


public class MainFeeCalculator {
    public static void main(String[] args) {

        File transactionfile = new File(new File("").getAbsolutePath(),"resource/Input_java.xlsx");
        ITransactionManager tranction= TrasactionReader.getTrasactionReaderInstance().readFile(FILETYPE.EXCEL,transactionfile);     
        tranction.displayTransactionReport();   


    }
}

I hope this will solve your issue.

Upvotes: 0

Related Questions