Out of Bounds Exception, need advice - java

I've read gone through the tutorials, so by all means, if you see something that I've done wrong here, please tell me so I can learn to better-participate on this site.
The getPerishedPassengers method below is giving me an out of bounds exception. I have researched and researched, and I seem to be populating the array properly, and I don't know what is wrong with the method that I've created either. Could someone guide me in the right direction as to how to overcome this exception? Thank you folks!
Here's the main/method:
int passengerMax = 2000;
int passengerActual = 0;
//Create a 2D array that will store the data from the .txt file
String[][] passengerData = new String[passengerMax][6];
//Constructor to read the file and store the data in the array
Titanic(String file) throws FileNotFoundException {
try (Scanner fileIn = new Scanner(new File(file))) {
//Conditional for reading the data
while (fileIn.hasNextLine()) {
//tab through the data to read
passengerData[passengerActual++] = fileIn.nextLine().split("\t");
}
}
}
public int getTotalPassengers() {
return passengerActual;
}
//Method for getting/returning the number of passengers that perished
public int getPerishedPassengers() {
int count = 0;
//For loop w/conditional to determine which passengers perished
for (int i = 0; i < getTotalPassengers(); i++) {
int survive = Integer.parseInt(passengerData[i][1]);
/*The program reads the file and if 1, the passenger survived. If 0,
the passenger perished. Conditional will add to the count if they
survived*/
if (survive == 0) {
count++;
}
}
return count;
}
Here's the stacktrace I'm receiving. I can include the test code as well if you folks would like. Thanks in advance:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at titanic.Titanic.getPerishedPassengers(Titanic.java:66)
at titanic.testTitanic.main(testTitanic.java:68)
Java Result: 1

From what I can see above, the issue is in the line:
int survive = Integer.parseInt(passengerData[i][1]);
My best guess, lacking your input file, is that when you are reading the file, at least one line creates an array of length 0 or 1. In all likelihood, if the last line of the file is an empty line, it would be this line which is causing your array out of bounds exception, as the split would create an array of length 0. Another cause would be a line which lacks any tab in it at all (say a space instead of tabs, etc.) will create a length 1 array, of which passengerData[i][1] will not exist, only passengerData[i][0] will.
Assuming that your input file does not have any lines which are improperly formatted / lack the appropriate number of tabs, I would suggest changing this line in the file read loop:
passengerData[passengerActual++] = fileIn.nextLine().split("\t");
to:
String incomingLine = fileIn.nextLine().trim();
if (null != incomingLine && !incomingLine.isEmpty()) {
passengerData[passengerActual++] = incomingLine.split("\t");
}

Related

Issue with parallel arrays and reading integers / doubles from file

I have an issue with parallel arrays and getting the program to read integers and doubles. For example, I have a text file with these values:
1234 99.58
5678 1854.99
The first number being an account number and the second number being the balance of the account. I'm not sure how to get them into a parallel array (int[] accountnumber, double[] balance) while going down the list of ideally 10+ accounts and balances.
I've tried filling the arrays separately without success, which doesn't feel like the most efficient method possible. I've tried breaking down the "(int = 0; i < maxAccts; i++)" so I could use the "i" variable for both without resetting it.
public static int readAccts(int[] acctNum, double[] balance, int maxAccts, File myinput, Scanner inputFile) throws IOException {
maxAccts = 0;
while(inputFile.hasNextInt()) {
//Test for reading integers accurately
//System.out.println(inputFile.nextInt());
maxAccts++;
inputFile.nextLine();}
//Test for maxAccts
System.out.println(maxAccts);
acctNum = new int[maxAccts];
balance = new double[maxAccts];
Scanner AccountFiller = new Scanner(myinput);
while(inputFile.hasNext());{
int i = 0;
while (i < maxAccts) {
acctNum[i] = AccountFiller.nextInt();
balance[i] = inputFile.nextDouble();
i++;}
//for (int i = 0; i < maxAccts; i++)
System.out.println(acctNum[1]);}
return maxAccts;
}
I keep getting this error below:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextDouble(Unknown Source)
At this point, I don't know why it's going wrong. In my head the cursor in the document should be right after the integer (account number), and I'm not getting an issue with that part.
You might want to fix your while loop
Your second while loop looks like this:
while(inputFile.hasNext());{
Which has a semicolon between the while and the curly brace, which means that the body of the loop is empty and after it is done looping, you run the code inside the curly braces.
The loop should be like this:
while(inputFile.hasNext()) {
This causes the error of reading the nextDouble since we just consumed the scanner's source until there is no next.
You might also want to check again how you want to read the file, since the first part doesnt really make much sense to me, it appears you just skip over all ints found in the file (while counting how many times you skip)

Nullpointer exception java runtime [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
The program looks slightly advanced; it is not. Simple manipulation of array.
The program compiles correctly, however, it encounters an exception run-time.
Exception in thread "main" java.lang.NullPointerException
at Ordliste.leggTilOrd(Tekstanalyse.java:85)
at Tekstanalyse.main(Tekstanalyse.java:23)
So there is something wrong with if(s.equalsIgnoreCase(ordArray[k])).
I cannot see why. It even provides the correct output.
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class Tekstanalyse {
public static void main(String[] args) throws FileNotFoundException {
Ordliste ol = new Ordliste();
ol.lesBok("scarlet.text");
ol.leggTilOrd("A");
}
}
class Ordliste {
private int i = 0;
private String[] ordArray = new String[100000];
private int antForekomster;
private int arrStorrelse = 0;
public void lesBok(String filnavn) throws FileNotFoundException {
File minFil = new File(filnavn);
Scanner scan = new Scanner(minFil);
while (scan.hasNextLine()) {
ordArray[i] = scan.nextLine();
//System.out.println(ordArray[i]);
i++;
arrStorrelse++;
}
System.out.println("Array size: " + arrStorrelse + " Capacity: " + ordArray.length);
}
public void leggTilOrd(String s) {
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
} else {
s = ordArray[arrStorrelse];
}
}
}
}
I'm pretty sure the error is right here:
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
} else {
s = ordArray[arrStorrelse]; // <- dangerous
}
}
As I said in the comment, ordArray could contain null elements if the read text file does not contain 100.000 lines of text. If this is the case, the above line would write null to s because s.equalsIgnoreCase(null) is false.
You should think about using a list instead of an array.
private List<String> ordList = new ArrayList<String>();
(or use a different variable name, it is up to you)
Then you can add new entries to the list using ordList.add(scan.nextLine());. This list won't contain any null elements and your mentioned problem should be gone.
I would highly recommend you to simply use a debugger to debug your code , but here goes:
in your lesBok method you fill your array with strings and make a counter arrStorrelse. to be the amount of elements in the array you made. however the array is filled for indexes 0 to n-1. and arrStorrelse is equal to N you did however allocate space in the array for this. so when in leggTilOrd() you iterate the first time and you enter the else clause you do this
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
}
else {
int arrStorrelse2=arrStorrelse;
s = ordArray[arrStorrelse];
}
in that else clause s is set to ordArray[arrStorrElse]; however arrStorrElse is at that moment one higher than the last intialised element of your array. so it sets s to the null pointer.
then the next iteration of your loop in the if clause
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
the s.equalsIgnoreCase() call is done on an s that is null that's where the null pointer exception comes from.
you need to change the arrStorrElse assignment you haven't explained what it should do so i can't do that for you also try to learn how to debug your code here is a usefull link:
http://www.tutorialspoint.com/eclipse/eclipse_debugging_program.htm
I have compiled and tested your code.
s.equalsIgnoreCase(null)
throws nullPointerException.
Maybe you should try to use ArrayList instead of Array to avoid iterating through nulls.
It took me some time to figure out why the NullPointerException occurs and I have to agree with Piotr and Tom: The NPE is caused by the line
s.equalsIgnoreCase(ordArray[k])
and a side-effect in your code. This side-effect is introduced by reassigning the parameter s in the else-branch to null (this value comes from ordArray[arrStorrelse]). After this reassignment happened, you will have something like this:
null.equalsIgnoreCase(ordArray[k])
And voila, there is the NullPointerException.

2D advice for nullpointer exception

I apologize in advance, I am a java noob.
I have this in a statement
if(a==0 && b<4)
{
value = ((elev[a][b]-elev[a+1][b])*0.00001* double "variable" ) ;
}
So my main question is would the following....
(elev[a][b]-elev[a+1][b])
return an int value (assuming that the array was initialized and populated with int values, and that for a==0 and b<4 none of the references are null.
Sorry in advance if this is silly. Please don't feel inclined to comment, but help would be appreciated. I haven't done a lot of this java stuff.
When i populated the array, I printed it's contents to make sure I was populating correctly, and everything is where it should be...
Alas, I get a null pointer error wherever that (elev[a][b] - elev[a+1][b]) is first referenced....yet i know that the values are being put there.
Next question. When i populate an array, if i want to reference the values,
while(input.hasNextInt())
{
elev[i][j] = input.nextInt(); <-- this is how i was doing it
}
of elev[][]... do i need to say
elev[i][j] = new input.nextInt();
or is how i was doing it sufficient. When i populated an ArrayList from a file I had to use the "new" prefix So i was trying to figure out why i would get a null there.
Like i said I did print the array after reading it from the file and it printed out everything was in its place.
Thanks everyone.
EDIT
ok sorry for simplicity sake i didn't put in the actual code of "value"
it is actually
double randKg = getRandKg(avgKgNitrogen[z]);
double gradient = 0.00001
double under = ((randKg *(elev[a][b] - elev[a+1][b]) * gradient));
2nd Edit
This is the code for how i populated.
try{
File file = new File(filename);
Scanner input = new Scanner(file);
int rows = 30;
int columns = 10;
int elev[][] = new int[30][10];
for(int i = 0; i < rows; ++i){
for(int j = 0; j < columns; ++j)
{
while(input.hasNextInt())
{
elev[i][j] = input.nextInt();
}
}
}
input.close();
}
catch (java.io.FileNotFoundException e) {
System.out.println("Error opening "+filename+", ending program");
System.exit(1);
}
3rd edit
So i am getting the null pointer here.....
(elev[a][b] - elev[a+1][b]) > 0 )
Which is why i originally asked. I have printed the array before when i populated and everything is where it should be.
You are getting a null pointer exception because double "variable" does not indicate to any integer or double value. Compiler is just trying to convert String 'variable' into double which is not possible. So, try eliminating the Double Quotes from "variable". Moreover you have not declared the data type of value variable.
Ignoring other problems in your code (covered by other answers), here's about your actual question:
If the code
if(a==0 && b<4) {
value = (elev[a][b] - elev[a+1][b]);
}
crashes with NullPointerException, it means elev is null. Assuming a and b are of type int, then there is no other way this can generate that exception (array out of bounds exception would be different). There are two options for the cause:
You execute above code before you do int elev[][] = new int[30][10];, so that elev still has the initial null value.
elev in the crashing line is a different variable than elev in initialization shown in the question.
And in you code, it seems to be 2. You create local elev in the initialization. It goes out of scope and is forgotten. You probably should have this initialization line in your method:
elev = new int[30][10];
And then you should have a class member variable instead of local variable in a method:
private int[][] elev;

reading string and integers from a text file in java

/*This assignment is to create 2 parallel arrays – jobs& salaries
*Read file from “careers.txt” into arrays
*one line – job
*next line –salary
*Sort Salaries {from highest}
*then swap jobs if salary swapped
*Display output of careers and salaries from the highest on a formatted table.
*
*/
package assignment7;
import java.util.*;//importing Scanner
public class Coordinator
{
public static void main(String[] args) throws Exception
{// the main method creates the arrays and calls on each method to perform
//its work.
String [] job = new String[20];//creating a string array having 20 spaces
int[] salary = new int[20];//creating an integer array having 20 spaces
int count;// number of spaces actually occupied in the array
**count = readFile(job, salary);**// calling a method to read text into both
//arrays and return the number of spaces
//occupied in the array
sorter(job,salary,count);// calling on method to arrange file from highest
//to lowest
display(job, salary,count);// calling on method present the output
}
public static int readFile(String[] jobber, int[] salaro) throws Exception
{ // this method reads a text file and copies into arrays and also
//returns the number of spaces occupied in the array
int n = 0; //keeps track of number of times a line is fed into an
//array
//set up a file class object linked up to the name of the file to
//be read
java.io.File unread = new java.io.File("career.txt");
// create a scanner instance to read the input from the file
Scanner infile = new Scanner(unread);
/*This while loop reads line of text into the arrays, it uses
* boolean
* function hasNextLine() and the created scanner instance.
*/
while (infile.hasNextLine() || infile.hasNextInt())
{
jobber[n] = infile.nextLine();
**salaro[n] = infile.nextInt()**;
n++;
}//end while
infile.close();//close scanner class
return n;// return number of spaces filled
}//end of readFile method
public static void sorter(String[] jobestic, int[] salawe, int z)
throws Exception
{// this method sorts the array from the highest paid job to the lowest.
boolean swapped;// keeps track of when a swap takes place
int i;// variable fo for loop
int temp;// helps in swap
String temp2;// helps in swap
do
{
swapped = false;
for (i= 0; i < z-1; i++)// a pass through the array
{
if (salawe[i+1] > salawe[i])
// if the number before it is less they swap
{
//swap starts
temp = salawe[i+1];
salawe[i+1] = salawe[i];
salawe[i] = temp;
//swaps the jobs too if the salary is swapped
temp2 = jobestic[i+1];
jobestic[i+1] = jobestic[i];
jobestic[i] = temp2;
swapped = true;
}// end if
}// end for
} while (swapped);
}// end sorter method
public static void display(String[] jobo, int[] salary5 ,int k) throws Exception
{
//this method displays the output as a formatted table
int i;
System.out.printf("%-60s%15s%n", "Job", "Salary");
for(i=0; i<k; i++)
System.out.printf("%-60s%,15d%n", jobo[i], salary5[i]);
}
}
Please Guys, what is wrong with this code? I have racked my brain over and over and can't figure out what is wrong.... I ran this code but i keep getting errors... The errors always indicate the bolded lines. The text file I'm trying to read from is below. I want to store the job titles in one array and the corresponding salaries in the other array. Like Parallel arrays. Please what is wrong with the code? I want to store the salaries as integers because i have format it as integers when I present the output.
Thank you.
Computer and Information Research Scientists
102190
Computer and Information Analysts
80460
Computer Systems Analysts
79680
Information Security Analysts
86170
Software Developers and Programmers
87100
Computer Programmers
74280
Software Developers(Applications)
90060
Software Developers(Systems Software)
99000
Web Developers
62500
Database and Systems Administrators and Network Architects
76880
Database Administrators
77080
Network and Computer Systems Administrators
72560
Computer Network Architects
91000
Computer Support Specialists
48900
Computer User Support Specialists
46420
Computer Network Support Specialists
59090
The error:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at assignment7.Coordinator.readFile(Coordinator.java:56)
at assignment7.Coordinator.main(Coordinator.java:25)
This question, or its equivalent, seems to get asked every few days.
When you call nextInt(), your scanner stops after the number. Then when you call nextLine() immediately afterwards, you're actually reading the new-line character at the end of the line that had the number on. You're not reading the next line. So on the next iteration of the loop, you're calling nextInt() when you've got non-numeric text lined up next in your scanner.
Add an extra call to nextLine() after every call to nextInt(), just to read that extra new-line character.

Null Pointer that makes no sense to me?

Im currently working on a program and any time i call Products[1] there is no null pointer error however, when i call Products[0] or Products[2] i get a null pointer error. However i am still getting 2 different outputs almost like there is a [0] and 1 or 1 and 2 in the array. Here is my code
FileReader file = new FileReader(location);
BufferedReader reader = new BufferedReader(file);
int numberOfLines = readLines();
String [] data = new String[numberOfLines];
Products = new Product[numberOfLines];
calc = new Calculator();
int prod_count = 0;
for(int i = 0; i < numberOfLines; i++)
{
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
if(data[i].contains("input"))
{
continue;
}
Products[prod_count] = new Product();
Products[prod_count].setName(data[1]);
System.out.println(Products[prod_count].getName());
BigDecimal price = new BigDecimal(data[2]);
Products[prod_count].setPrice(price);
for(String dataSt : data)
{
if(dataSt.toLowerCase().contains("imported"))
{
Products[prod_count].setImported(true);
}
else{
Products[prod_count].setImported(false);
}
}
calc.calculateTax(Products[prod_count]);
calc.calculateItemTotal(Products[prod_count]);
prod_count++;
This is the output :
imported box of chocolates
1.50
11.50
imported bottle of perfume
7.12
54.62
This print works System.out.println(Products[1].getProductTotal());
This becomes a null pointer System.out.println(Products[2].getProductTotal());
This also becomes a null pointer System.out.println(Products[0].getProductTotal());
You're skipping lines containing "input".
if(data[i].contains("input")) {
continue; // Products[i] will be null
}
Probably it would be better to make products an ArrayList, and add only the meaningful rows to it.
products should also start with lowercase to follow Java conventions. Types start with uppercase, parameters & variables start with lowercase. Not all Java coding conventions are perfect -- but this one's very useful.
The code is otherwise structured fine, but arrays are not a very flexible type to build from program logic (since the length has to be pre-determined, skipping requires you to keep track of the index, and it can't track the size as you build it).
Generally you should build List (ArrayList). Map (HashMap, LinkedHashMap, TreeMap) and Set (HashSet) can be useful too.
Second bug: as Bohemian says: in data[] you've confused the concepts of a list of all lines, and data[] being the tokens parsed/ split from a single line.
"data" is generally a meaningless term. Use meaningful terms/names & your programs are far less likely to have bugs in them.
You should probably just use tokens for the line tokens, not declare it outside/ before it is needed, and not try to index it by line -- because, quite simply, there should be absolutely no need to.
for(int i = 0; i < numberOfLines; i++) {
// we shouldn't need data[] for all lines, and we weren't using it as such.
String line = reader.readLine();
String[] tokens = line.split("(?<=\\d)\\s+|\\s+at\\s+");
//
if (tokens[0].equals("input")) { // unclear which you actually mean.
/* if (line.contains("input")) { */
continue;
}
When you offer sample input for a question, edit it into the body of the question so it's readable. Putting it in the comments, where it can't be read properly, is just wasting the time of people who are trying to help you.
Bug alert: You are overwriting data:
String [] data = new String[numberOfLines];
then in the loop:
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
So who knows how large it is - depends on the success of the split - but your code relies on it being numberOfLines long.
You need to use different indexes for the line number and the new product objects. If you have 20 lines but 5 of them are "input" then you only have 15 new product objects.
For example:
int prod_count = 0;
for (int i = 0; i < numberOfLines; i++)
{
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
if (data[i].contains("input"))
{
continue;
}
Products[prod_count] = new Product();
Products[prod_count].setName(data[1]);
// etc.
prod_count++; // last thing to do
}

Categories

Resources