This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 6 years ago.
Brief description
I am currently writing a massive (For my skill level) java program with my first UI. My goal is to make the program use the UI to save career information to a text file and allow it to read that file into a JTable, these two actions are done through JButtons.
The file uses a # between variables and is in the format:
name#placeOfWork#description#highestSalary#lowestSalary#indexOfDegree#indexOfDegreeLevel and studYears#yearOfMatriculation#
The issue arose when I tried to instantiate a Career constructor (Code below) from the file by splitting the line into the necessary parts, I have no idea how this is giving me an ArrayIndexOutOfBounds exception as it seems to be within the array's boundaries...
The Career's parameterised constructor: (Career)
public final int[] ARR_STUDY_YEARS = { 0, 0, 1, 2, 4, 6, 10 };
public final String ARR_DEGREE[] = { "None", "Commerce", "Science", "Arts", "Computer Sciences", "Education",
"Medicine", "Engineering" },
ARR_DEGREE_LEVEL[] = { "None", "Matriculent", "Undergraduate", "Associate", "Bachelor", "Masters",
"Doctorate" };
// Variables
private String name, setting, description, degree, degreeLevel, qualification;;
private int highestSalary, lowestSalary, avgSalary, sYears, matricYear;
public Career(String name, String setting, String description, int highestSalary, int lowestSalary,
int degreeNo, int degreeLevelNo, int matricYear){
this.name = name;
this.setting = setting;
this.description = description;
this.highestSalary = highestSalary;
this.lowestSalary = lowestSalary;
sYears = ARR_STUDY_YEARS[degreeLevelNo];
degreeLevel = ARR_DEGREE_LEVEL[degreeLevelNo];
degree = ARR_DEGREE[degreeNo];
this.matricYear = matricYear;
}
The Code giving me an error: (CareerUI)
JButton btnDisplay = new JButton("Display");
btnDisplay.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ArrayList<Career> careerList = new ArrayList<Career>();
File file = new File("Careers.txt");
try {
Scanner reader = new Scanner(file);
while (reader.hasNextLine()) {
String[] line = reader.nextLine().split("#");
Career career = new Career(line[0], line[1], line[2], Integer.parseInt(line[3]), Integer.parseInt(line[4]),
Integer.parseInt(line[5]), Integer.parseInt(line[6]), Integer.parseInt(line[7]));
//^ This constructor is on line 200
careerList.add(career);
}
reader.close();
String[][] cMatrix = new String[careerList.size()][6];
String[] header = { "Name", "Setting", "Description", "Average Salary", "Tertiary Qual. Required",
"Qualification" };
for (int i = 0; i < cMatrix.length; i++) {
for (int j = 0; j < cMatrix[i].length; j++) {
Career c = careerList.get(j);
cMatrix[i] = c.toTableSummary();
}
}
JTable table = new JTable(cMatrix, header);
// table.set
table.setBounds(519, 53, 489, 437);
panel.add(table);
} catch (FileNotFoundException ex) {
System.out.println("There was an error while reading your file");
}
}
});
The File: (Careers.txt)
Chartered Accountant#Office#Balances finances#100000#80000#1#4#2017#
Plumber#House Calls#Fixes Plumbing#50000#10000#0#0#2019#
Doctor#Clinic#Treats illness#150000#50000#6#6#2016#
Architect#Construction Firm#Designs Buildings#80000#50000#6#5#2018#
The Error:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1
at career.CareerUI$3.actionPerformed(CareerUI.java:200)
Update
Just did a test with converting a text file into a multi dimensional array and it worked, the code is below. I might be close to figuring this out.
public class ScanToArray {
public static void main(String[] args) {
try {
Scanner scFile = new Scanner(new File("test.txt"));
int x = 0;
String[][] multi = new String[5][5];
while (scFile.hasNextLine()){
String[] next = scFile.nextLine().split("#");
multi[x][0] = next[0];
multi[x][1] = next[1];
multi[x][2] = next[2];
multi[x][3] = next[3];
multi[x][4] = next[4];
x++;
}
scFile.close();
int ln = 0;
for (int i = 0; i < multi.length; i++) {
for (int j = 0; j < multi[i].length; j++) {
if(i>ln){
System.out.println();
ln = i;
}
System.out.print("|" +multi[i][j] +"|");
}
}
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "Error: File not found");
}
}
}
The File used (test.txt)
0.0#0.1#0.2#0.3#0.4
1.0#1.1#1.2#1.3#1.4
2.0#2.1#2.2#2.3#2.4
3.0#3.1#3.2#3.3#3.4
4.0#4.1#4.2#4.4#4.4
The output:
|0.0||0.1||0.2||0.3||0.4|
|1.0||1.1||1.2||1.3||1.4|
|2.0||2.1||2.2||2.3||2.4|
|3.0||3.1||3.2||3.3||3.4|
|4.0||4.1||4.2||4.4||4.4|
Going to mess around and see if I can convert that to a Jtable and then try to work out where I went wrong initially.
Note: I am not asking what a arrayindexoutofbounds is, I am asking why this particular code is giving me it.
There are few problems with your code:
(1) In the 4th line of your input, there is 7th index (if you split with #), which breaks when you try to get line[7], which will throw ArrayIndexOutOfBoundsException
Buildings#80000#50000#6#5#2017#
(2) You will not be able to parse the 6th element using Integer.parseInt(line[6]) as it throws NumberFormatException
(3) The input data is not right even in the 3rd line, it has more than 7 indexes after split, which does not throw any exceptions (as you are retrieving upto 7 indexes), but ensure that correct data is passed as input.
sYears = ARR_STUDY_YEARS[degreeLevelNo];
degreeLevel = ARR_DEGREE_LEVEL[degreeLevelNo];
You most likely don't want to use the same variable as index to different arrays.
Related
i want to print my availaiblebooksbooks array. I am doing this using for loop.
initial output
welcome..., what do you want to do in library
choose any one performable action
1.addbook
2.purchasbook
3.returnbook
4.showavilaiblebook
I am putting user input 4.showavilaiblebook
after putting input is m getting this.
action not found
action not found
action not found
where it should print:-
Think and grow rich
how to influence pepoles
Richest man in bablyon
Jeet ya har
great words win heart
Time management
positive thinking
power thinking
subconcious mind
My java code
public class OnlineLibrary {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("welcome..., what do you want to do in library");
String [] actionlist = {"choose any one performable action", "1.addbook","2.purchasbook","3.returnbook","4.showavilaiblebook"};
for(int i = 0; i<actionlist.length; i++) {System.out.println(actionlist[i]); }
//list of library books
String [] availaiblebooksbooks = {"Think and grow rich", "how to influence pepoles", "Richest man in bablyon", "Jeet ya har", "great words win heart","Time management", "positive thinking", "power thinking","subconcious mind"};
String input = scan.next();
for(int i = 1; i<actionlist.length; i++) {
String actionno = actionlist[i];
if (input.equals(actionno)) { }
else if (input.equals(actionno)) { }
else if (input.equals(actionno)) { }
else if (input.equals(actionno)) { for(int p = 0; p<availaiblebooksbooks.length; p++) { System.out.println(availaiblebooksbooks[p]); }}
else {System.out.println("action not found");}
}
}
}
The expected answer is obtained by keeping its direct value of the arrayitem. But I want to know what is the problem with this.
Try something like this, or use a switch statement based on the "input":
String input = scan.next();
if (input.equals("4")) {
for(int p = 0;p < availaiblebooksbooks.length; p++) {
System.out.println(availaiblebooksbooks[p]);
}
}... else if (otherinputs) {
.
.
}
So I am trying to create an object array that from a text file. The objects I am placing in the array are people objects with 4 parameters. 1st name, last name, an ID number and a height. The text file has a certain number of lines and each element is separated by an exclamation mark. I am trying to take each of the 4 elements to create an object and then place that object into an object array. Here is my code up until now. Also because I am new to java, there is not a lot that I know so the code needs to be simple.
import java.io.File;
import java.io.IOException;
import java.util.*;
public class Participants {
public static void main(String[] args) {
String array[] = new String[35];
Object participants[] = new Object[35];
int count = 0;
int counter = -1;
try {
File myFile1 = new File("Participants.txt");
Scanner scan1 = new Scanner(myFile1);
while (scan1.hasNext()) {
counter++;
array[counter] = scan1.next();
}
} catch (IOException ioe) {
System.out.println("The file can not be read");
}
for (int i = 0; i < array.length; i++) {
StringTokenizer st = new StringTokenizer(array[i], "!");
while (st.hasMoreTokens()) {
People person = new People(st.nextToken(), st.nextToken(), st.nextToken(),
st.nextToken());
participants[i] = person;
}
}
}
}
I commented that your code basically looks okay. There are some problems I spotted, and I think you may be running into them. You are probably getting a
Exception in thread "main" java.lang.NullPointerException
at java.util.StringTokenizer.<init>(Unknown Source)
at java.util.StringTokenizer.<init>(Unknown Source)
at Participants.main(Participants.java:22)
because arrays[i] is empty in
StringTokenizer st = new StringTokenizer(array[i], "!");
which is because you allocate 35 entries:
String array[] = new String[35];
and the file contains less lines than that. At least, that's what I'm getting it with this input file:
A!B!C!D
E!F!G!H
I!J!K!L
which is to be expected.
If I change the first line of the input file into
A!B!C
I get
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(Unknown Source)
at Text2ObjArray.main(Text2ObjArray.java:28)
which is because you only check once for a token, but then proceed to read four:
while (st.hasMoreTokens()) {
Person person = new Person(st.nextToken(), st.nextToken(), st.nextToken(), st.nextToken());
I'll update with a solution, if it is needed, but here are two suggestions:
1) use an ArrayList instead of an array[]:
2) Check what you parse: make sure there are 4 tokens per line, and deal with the exceptional case that they are not 4.
UPDATE
Basically, there's nothing wrong with your program. You already know "
How to put values from a text file into an object array in java?".
Your program runs just fine if you feed it a file with exactly 35 lines containing at least 3 exclamation marks each. If not, it throws the appropriate exceptions:
a NullPointerException if there are less than 35 lines and
an ArrayIndexOutOfBoundsException if there are more, and
a NoSuchElementException if there are less than 3 exclamation marks on any of the lines.
(Unless, there is a problem is in the People class which is unlikely if it is a POJO).
Your code only needed a few minor changes to make it work for files with other content. I've kept it simple:
import java.io.File;
import java.io.IOException;
import java.util.*;
public class Text2ObjArray {
public static void main(String[] args) {
Person[] participants = loadFile(new File(args.length > 0
? args[0] : "Participants.txt"));
for (Person p : participants)
System.out.println("Participant: " + p);
}
I split off main merely as good practice - see 'top-down' and 'bottom-up'.
To address the NullPointerException and ArrayIndexOutOfBoundsException We'll use an ArrayList instead of an array[] to keep track of the lines we read from the file. The advantage of an ArrayList is that it can grow and shrink, which is useful if you don't know for sure if "Participants.txt" always contains 35 lines.
Also it saves us from replacing our array with a bigger one when it's full. It's a cheap, handy upgrade from an array[], and all that has changed is writing
array.get(i) instead of array[i]
array.set(i,foo) instead of array[i]=foo and
array.add(foo) instead of array[counter++]=foo and
array.size() instead of array.length. It is a dynamic array, so you can insert into any position, remove etc.
private static Person[] loadFile(File file) {
List<String> lines = new ArrayList<>();
try (Scanner scan1 = new Scanner(file)) {
while (scan1.hasNext())
lines.add(scan1.next());
} catch (IOException e) {
System.out.println("File read error: " + e.getMessage());
}
This section is changed only in that it reads up to 4 tokens, dealing with the NoSuchElementException:
Person participants[] = new Person[lines.size()];
for (int i = 0; i < lines.size(); i++) {
StringTokenizer st = new StringTokenizer(lines.get(i), "!");
String[] fields = new String[4];
for (int k = 0; k < fields.length && st.hasMoreTokens(); k++)
fields[k] = st.nextToken();
participants[i++] = new Person(fields[0], fields[1], fields[2], fields[3]);
}
return participants;
}
}
To run it successfully you'll need to replace Person to People or use this Person class:
public class Person {
private String id;
private String lName;
private String fName;
private String height;
public Person(String id, String fName, String lName, String height) {
this.id = id;
this.fName = fName;
this.lName = lName;
this.height = height;
}
public String toString() {
return "Person[" + id + ": " + lName + ", " + fName + ", " + height + "]";
}
}
I hope that this has been helpful.
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 7 years ago.
So this is my text file:
CareFlight101 0 2
PiperCub 2 99
AirAmbulance 2 1
TransWorld122 2 5
Cessna152 3 99
Eastern429 4 10
They are suppose to be aircrafts name followed my arrival time and landing priority.
I am trying to splitting it so that it takes each into account. I am having trouble splitting it though because it it throwing a 'java.lang.ArrayIndexOutOfBoundsException: 1' error
This is what I have so far:
public class TheAircrafts {
public static ArrayList<Plane> planeList;
public static void main(String[] args){
try {
File f = new File("sample_data_p3.txt");
Scanner sc = new Scanner(f);
List<Plane> people = new ArrayList<Plane>();
while(sc.hasNextLine()){
String line = sc.nextLine();
String[] details = line.split("\\s+");
String flightID = details[0];
int arrivalTime = Integer.parseInt(details[1]);
int landingPriority = Integer.parseInt(details[2]);
Plane p = new Plane(flightID, arrivalTime, landingPriority);
planeList.add(p);
}
for(Plane p: planeList){
System.out.println(p.toString());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
And in my plane class I have:
public class Plane {
private String flightID;
private int arrivalTime;
private int landingPriority;
private int numRunways;
public Plane(String flightID, int arrivalTime, int landingPriority) {
this.setflightID(flightID);
this.arrivalTime = arrivalTime;
this.landingPriority = landingPriority;
}
followed by get and set and get methods for each of the variables
You get a IndexOutOfBoundsException in this case when there is a line which not more than i elements seperated by a space.
In your case there is a line which has only one word in it. And hence when you try to get the second word which didn't exist you get an Exception.
To avoid getting so, you can check if that line has 3 words or not.
String []details = line.split("\\s+");
if(details.length == 3)
{
//do your setting
}
I'm trying to read these names from a text file, but getting an error. Here's the relevant part of my main method, and the method in question:
public class Prog4
{
int mostVoteCount = 0;
int mostVotes = 0;
int mostVotesIndex = 0;
int fewestVoteCount = 0;
int fewestVotes = 0;
int fewestVotesIndex = 0;
String[] candidateArray;
int[] votesArray;
public static void main(String args[]) throws Exception
{
//Scanner stdin = new Scanner(System.in);
Scanner stdin = new Scanner(new File("test.txt"));
int num_votes, num_candidates, election_num = 1;
System.out.println("Welcome to Prog4!\n");
Prog4 p4 = new Prog4();
while (stdin.hasNextLine())
{
System.out.println("Results for election " + election_num);
p4.read_candidates(stdin, p4.candidateArray);
p4.read_votes(stdin, p4.votesArray);
System.out.println("Total votes: " + p4.votesArray.length);
}
System.out.println("Done. Normal termination of Prog4.");
}
and the method in question:
public void read_candidates(Scanner stdin, String candidates[])
{
int candidateCount = 0;
candidateCount = (stdin.nextInt());
for (int i = 0; i < candidateCount; i++)
candidates[i] = (stdin.next());
}
Here's my test data used in the "test" text file:
4
Owen
Jack
Scott
Robbie
15 0 1 1 2 3 1 0 0 0 0 1 2 2 1 1
Is this the stack trace?
java.lang.NullPointerException
at Prog4.read_candidates(Prog4.java:75)
at Prog4.main(Prog4.java:35)
You're never instantiating your candidateArray and votesArray, so they are null when you pass them to the read_candidates method. I'm guessing it is failing on the line:
candidates[i] = (stdin.next());
You're basically attempting to do something with a null object (the candidates object in this case). At some point in your code you'll have to do something like candidateArray= new String[], and same thing for the votesArray, before you attempt to use them.
You need to initialize your array "candidates" before you do the assignment
public void read_candidates(Scanner stdin, String candidates[]) {
int candidateCount = 0;
candidateCount = (stdin.nextInt());
candidates = new String[candidateCount]; // here initialize your array
for (int i = 0; i < candidateCount && stdin.hasNext(); i++){
String data = stdin.next();
System.out.print(data + " ");
candidates[i] = data;
}
}
it can be an outfobound exaception so please be careful with the line candidateCount = (stdin.nextInt());
you may get exception here so calculate length correctly candidateCount = candidates.length;
Check the location of test.txt. Based the trace, your Scanner object being passed to read_candidates is null. Be sure that you can read the file from the specified location.
I have some problem in parsing one String as
String str="0|$5th std~~Pramod Deore|^97.0|^970.0|^1.02|^871.0600000000001|^S|^98.94|^5996.9400000000005|^12|^166|^|$7th std~~Vishal Chaudhary|^20.0|^220.0|^111.0|^-2000.0|^|^2220.0|^0.0|^110|^22222~Yogesh Gadage|^100.0|^3000.0|^10.0|^2000.0|^|^1000.0|^0.0|^16|^03~12|^111.0|^134532.0|^11.0|^133311.0|^B|^1221.0|^0.0|^45|^12~Chetan Patil|^200000.22|^2066002.2726|^-0.1500000549999395|^2096002.3166|^H|^-30000.044|^0.0|^20|^FEF-D~Sandeep Deshmukh|^-1.0|^-10.0|^0.0|^0.0|^|^0.0|^123.0|^29|^JPPWR~Yogita Gade|^25.0|^250.0|^100.25|^-2256.25|^X|^2506.25|^0.0|^30|^302|^|$";
Here in String I have 2 main records seperated by "~~"supppose 1. 5th std and 2. 7th std. Then in second record(i.e 7th std) there are 6 records seperated by "~". Now I want to parse this response and store values of each individual records.
let take one record from 2nd one.
Sandeep Deshmukh|^-1.0|^-10.0|^0.0|^0.0|^|^0.0|^123.0|^29|^JPPWR
In short What I want is- I want to know say -"Sandeep Deshmukh" is from 7th Std. and 1.0 is his grade, 10.0 is his 2nd grade ......and JPPWR is his city short name
Then I must know it is from 2nd main record (i.e 7 th std) and also store all values of this record which is separated by "|^". How to do this. I had tried following code.
import java.util.ArrayList;
class ParseTest
{
String str="0|$5th std~~Pramod Deore|^97.0|^970.0|^1.02|^871.0600000000001|^S|^98.94|^5996.9400000000005|^12|^166|^|$7th std~~Vishal Chaudhary|^20.0|^220.0|^111.0|^-2000.0|^|^2220.0|^0.0|^110|^22222~Yogesh Gadage|^100.0|^3000.0|^10.0|^2000.0|^|^1000.0|^0.0|^16|^03~12|^111.0|^134532.0|^11.0|^133311.0|^B|^1221.0|^0.0|^45|^12~Chetan Patil|^200000.22|^2066002.2726|^-0.1500000549999395|^2096002.3166|^H|^-30000.044|^0.0|^20|^FEF-D~Sandeep Deshmukh|^-1.0|^-10.0|^0.0|^0.0|^|^0.0|^123.0|^29|^JPPWR~Yogita Gade|^25.0|^250.0|^100.25|^-2256.25|^X|^2506.25|^0.0|^30|^302|^|$";
public static void main(String[] args)
{
ParseTest pt = new ParseTest();
pt.parse();
}
public void parse()
{
System.out.println (str);
ArrayList<String> stockrows = parseResponse(str,"|$");
for (int i=1;i<stockrows.size();i++)
{
System.out.println("iiii"+i+":::"+stockrows.get(i));
//parse with ~~
ArrayList<String> stockrows1 = parseResponse(str,"~~");
for (int j=0;j<stockrows1.size();j++)
{
System.out.println("jjjj"+j+"::::"+stockrows1.get(j));
//parse with ~
ArrayList<String> stockrows2 = parseResponse(str,"~");
for (int k=0;k<stockrows2.size();k++)
{
System.out.println("kkkkkk"+k+"::::"+stockrows2.get(k));
}
}
}
}
public static ArrayList<String> parseResponse(String input, String delimeter) {
ArrayList<String> parsed_strings = new ArrayList<String>();
while (true) {
int i = input.indexOf(delimeter);
if (i >= 0) {
String s = input.substring(0, i);
parsed_strings.add(s.trim());
input = input.substring(i + delimeter.length(), input.length());
} else {
break;
}
}
if (parsed_strings.size() < 1) {
parsed_strings.add(input);
}
return parsed_strings;
}
}
Any help will be apprecited. Thanks in advance
String str="0|$5th std~~Pramod Deore|^97.0|^970.0|^1.02|^871.0600000000001|^S|^98.94|^5996.9400000000005|^12|^166|^|$7th std~~Vishal Chaudhary|^20.0|^220.0|^111.0|^-2000.0|^|^2220.0|^0.0|^110|^22222~Yogesh Gadage|^100.0|^3000.0|^10.0|^2000.0|^|^1000.0|^0.0|^16|^03~12|^111.0|^134532.0|^11.0|^133311.0|^B|^1221.0|^0.0|^45|^12~Chetan Patil|^200000.22|^2066002.2726|^-0.1500000549999395|^2096002.3166|^H|^-30000.044|^0.0|^20|^FEF-D~Sandeep Deshmukh|^-1.0|^-10.0|^0.0|^0.0|^|^0.0|^123.0|^29|^JPPWR~Yogita Gade|^25.0|^250.0|^100.25|^-2256.25|^X|^2506.25|^0.0|^30|^302|^|$";
String a[] = str.split("~~|~");
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}