# A few questions about java

• Java
Gold Member
The code I'm working with
Java:
import java.io.*;
import java.util.*;

public class ProgressReport{

Student[][] student = new Student[1][1];
int[] scores = {0,0,0,0,0};
String name = "";

public ProgressReport() throws FileNotFoundException{
}

@SuppressWarnings("resource")
Scanner s = new Scanner(file);
Scanner line;
int[] sec = {0,0};
int k = -1;
int j = -1;

while(s.hasNextLine())
{
String str = s.nextLine();
k++;
if(str.length() == 1)
{
j++;
sec[j] = Integer.parseInt(str);
}
else{
line = new Scanner(str);
while(line.hasNext())
{
try
{
for(int i =0; ;i++)
{
scores[i] = Integer.parseInt(line.next());
}
}
catch(Exception e)
{
while(line.hasNext())
{
name = line.next();
}

}

}
student[j][k] = new Student(name, scores);

}

}
System.out.println(student);
}

}
1:
How do I initialize a 2d array of objects? I keep getting crashes on a line that tries to fill an array with objects.
Student[][] student = new Student[1][1];
my plan is to use add[][] to add a row when there is a new course section found within a document and add a column when there is a new student found within the section within the document (a text file)

I keep crashing upon my first attempt to execute the following line:
student[j][k] = new Student(name, scores);

2:
Is my method an efficient way to read a text file and tokenize it? I feel like this might be the root of my error. I have a break point set on the line
student[j][k] = new Student(name, scores);
and it crashes in first iteration. Here is a little bit from my debugger.
name = "84" (id=30)
scores is an array of 0's, as expected
student -> sudent[1] -> null

I am not sure why my variable is null there. I'm assuming that it is saying i have 1 d of student arrays, and that array is null. I'm not sure why. So basically a 1x1 array with that element equal to null. I'm not sure what to do here. What am I doing incorrectly?

Mentor
Why is the student array two dimensional? What does the j and k represent?

I would expect the student array to be one dimensional. Basically, we have a list of students.

The line student[1][1] creates an array of one element at index 0,0 so you can't add more students.

Most programmers would use an ArrayList of students and use its add method to add a new student to the list. An arraylist will grow as you add more students whereas in your example you are limited to whatever you define in your program.

https://www.tutorialspoint.com/java/java_arraylist_class.htm

QuantumQuest
Gold Member
I agree with jedishrfu. Your incoming data is nothing more than data for a simple list of students. Since you appear to have a Student constructor that contains names and scores, you just need to create a simple ArrayList of Students.

Also, based on your code, it looks as if you expect every name and score to be on a separate line instead of the usual way of storing data like that (comma separated values). That doesn't sound right and even if true, the code is overly complex to read that. If you can supply a sample of your input data, that would help.

QuantumQuest and jedishrfu
Gold Member
I need to separate them into course sections, and for the assignment, it is given that students[][]. Also, as for array lists, we haven't technically covered them in class yet. I was basically planning on using something to the effect of
and the +1 would be added in where necessary (so when j increments, we use the first [] +1 and k = students[].length +1) and vice versa when k increments, however, I would need an if statement or some way to check if we are at max index, so if(k == students[].length -1 && s.hasNextLine() && s.nextLine.length() != 1) {//add length in k dimension}

We have
5
Johnson 90 80 70 60 50
Abraham 98 78 67 87 56
...
6
[another name I'm not creative and don't have the file on hand] 98 67 87 89 65
...

Gold Member
In other words, the file is given, and I'm given a UML diagram or whatever it's called that gives methods and objects and basically spells out what everything needs to do.
It is a bit more complex than necessary, as we have 2 sections only, and I could literally just make it to read that file, but I want it to work for an arbitrary number of course sections, students, and test scores.

I might still be doing it in a stupid way, though.

Gold Member
I pretty much just want to know if it's my tokenization that's failing or if it's my initialization of students[][] that is incorrect, or something else entirely that's causing me to crash on the line that fills students[j][k]. I haven't java'd in about 4 years and am retaking a class to get the necessary credit hours and replace a grade.

Gold Member
5
Johnson 85 96 97 91 84
Aniston 80 90 95 93 48
Cooper 78 81 89 90 73
Gupta 92 83 30 69 87
Blair 23 45 96 38 59
6
Clark 60 85 45 39 67
Kennedy 77 31 52 74 83
Bronson 93 94 89 77 97
Sunny 79 85 85 93 82
Smith 85 72 82 75 63
Diana 85 72 49 75 63

Here is the actual file

Gold Member
and I was just informed that the number at the top isn't the section number, it's the number of students in that section, so that solves that, I think. I will post back after lab.

Gold Member
Given the file, it makes a little more sense why they would want a 2-D array. The first array is being used to track sections and the second tracks the students in that section. It looks like you will have to read through the entire file to determine the number of sections (i) first and then read through it a second time to populate the students (i, j). The number of students in the section will determine the value of j for each i. There's lots of ways to do this and plenty of ways to mess it up.

Gold Member
Haha. Thanks borg. Here is my current place. I think I am able to avoid reading through the file multiple times. This should be 100% general except for the number of scores (which I will generalize eventually, just not right now).
Java:
import java.io.*;
import java.util.*;

public class ProgressReport{

Student[][] student;
Student[][] col;

int[] scores = {0,0,0,0,0};
String name = "";

public ProgressReport() throws FileNotFoundException{
student = new Student[1][1];
}

@SuppressWarnings("resource")
Scanner s = new Scanner(file);
Scanner line;
int[] sec = {0,0};
int[] moar;
int k = -1;
int j = -1;

while(s.hasNextLine())
{
String str = s.nextLine();

if(str.length() == 1)
{
j++;
k=0;
if(j>2){
moar = new int[sec.length+1];
for(int ii = 0;ii<sec.length+1;ii++){
moar[ii] = sec[ii];
}
sec = moar.clone();
}
sec[j] = Integer.parseInt(str);
student[j] = new Student[sec[j]];
for(int jj = 0; jj<j; jj++){
for(int kk = 0 ; kk<k;kk++){
}
}
}
else{
line = new Scanner(str);
while(line.hasNext())
{
name = line.next();

System.out.println(j + k);
try
{

for(int i =0; i<scores.length ;i++)
{
name = line.next();
scores[i] = Integer.parseInt(name);
System.out.println(scores);
}
}
catch(Exception e)
{
k++;
while(line.hasNext())
{
System.out.println(name);
}

}

}
student[j][k] = new Student(name, scores);

}

}
System.out.println(student);
}

}

I'm actually not sure if I need both col[][] and add[][]. I think that I might need both in order to avoid losing data, but am not 100% sure yet. I'm getting an index out of bounds error, and am also getting a really weird output for my syso.println (j+k). I'm actually going to take a break from this for now and may or may not get back to it before tonight. I have a little break before class, but want to step away from this for a little while.

Gold Member
if(str.length() == 1)
Might want to rethink that. What if there are more than 9 students?

BiGyElLoWhAt
Gold Member
The code I'm working with
1:
How do I initialize a 2d array of objects? I keep getting crashes on a line that tries to fill an array with objects.
Student[][] student = new Student[1][1];
my plan is to use add[][] to add a row when there is a new course section found within a document and add a column when there is a new student found within the section within the document (a text file)

I keep crashing upon my first attempt to execute the following line:
student[j][k] = new Student(name, scores);

2:
Is my method an efficient way to read a text file and tokenize it? I feel like this might be the root of my error. I have a break point set on the line
student[j][k] = new Student(name, scores);
and it crashes in first iteration. Here is a little bit from my debugger.
name = "84" (id=30)
scores is an array of 0's, as expected
student -> sudent[1] -> null

I am not sure why my variable is null there. I'm assuming that it is saying i have 1 d of student arrays, and that array is null. I'm not sure why. So basically a 1x1 array with that element equal to null. I'm not sure what to do here. What am I doing incorrectly?

Haha. Thanks borg. Here is my current place. I think I am able to avoid reading through the file multiple times. This should be 100% general except for the number of scores (which I will generalize eventually, just not right now).
I'm actually not sure if I need both col[][] and add[][]. I think that I might need both in order to avoid losing data, but am not 100% sure yet. I'm getting an index out of bounds error, and am also getting a really weird output for my syso.println (j+k). I'm actually going to take a break from this for now and may or may not get back to it before tonight. I have a little break before class, but want to step away from this for a little while.

I totally agree to what jedishrfu points out:

Most programmers would use an ArrayList of students and use its add method to add a new student to the list.

But even if you can't do it this way right now, I recommend putting the appropriate comments in your code, so everyone trying to help, would avoid getting into guesswork. This would even help you directly spotting syntactical or logical errors.

Last edited:
Gold Member
@Borg
Yes, I have thought of that, but I'm not sure how far to go. I should be able to go at least 2, as at bare minimum a name should consist of 1 letter and there should be 1 test score, which would have at least 1 digit. I could probably get away with upwards of 5, but 3 would give me 999 students, which is probably good enough. This is essentially more for practice than anything (it's an assignment, but I'm doing it excessively to shock myself back into java).
@QuantumQuest
I will add in comments next time I upload code. Do you think at the top would be sufficient?

Mentor
I will add in comments next time I upload code. Do you think at the top would be sufficient?
I'll answer in place of @QuantumQuest, but I doubt that he will disagree. Comments just at the top are not sufficient. You should also have comments spread throughout your code, both for your sake (you'll forget what you did and why in a few weeks) as well as for readers who aren't intimate with your thought process. The comments should not merely restate what the code is doing: they should give some explanation of why you are doing what you're doing.

Also, your variable names should be self-explanatory. I have no idea what one of your variables, moar, is supposed to represent, which makes it harder to decipher what you're trying to do.

QuantumQuest and jedishrfu
Gold Member
Yea I see. I will add in a few in line as well, but I will turn in my code this weekend and likely never touch it again.

Mentor
Another minor point is in how you are setting up and indexing through your student array.

Most programmers will initialize the j and k to zero not -1 and increment them after the operations have been done to store the student information. This may seem arbitrary but it produces cleaner code in the long run.

Also I'd add a comment on the meaning of the j and k so that you'll know what they represent when you come back to the code.

Actually I'd also give them more meaningful names as we tend to use j and k for for loops but in your case the j and k represent the actual number of students added to your table and could be used in a followon for loop to generate a student by student report where the j and k would be the number of iterations to make.

Consider nStudents and nClasses or something similar instead of j and k.

BiGyElLoWhAt and QuantumQuest
Gold Member
I'm having a problem in this section of the code:
Java:
                    try
{

for(int i =0; i<scores.length ;i++)
{
name = line.next(); //set name equal to the next token
scores[i] = Integer.parseInt(name); //check if name is an int
//System.out.println(scores[i]);
}
}
catch(Exception e)
{
k++; //else increment k and move to the next index for a new student
System.out.println(k); // print the index of the student THIS DOESN'T PRINT AT ALL
while(line.hasNext())
{
System.out.println(name);
}

}

}
This isn't behaving as though I think it should. k is never printing in my console. I just have a list of the names of the students. Here is the full code as is (I know I'm still missing a few comments, but hopefully I added enough into make everything clear)
Java:
import java.io.*;
import java.util.*;

public class ProgressReport{

Student[][] student;  //An array of student objects, the one we care about
Student[][] add;  //A secondary array, used for adding length to the student array (in number of students
Student[][] col;  //A preemptive strike, presumably I will need a third array for columns, currently unused

int[] scores = {0,0,0,0,0};  // Scores for a section
String name = "";  //Name of the student

public ProgressReport() throws FileNotFoundException{
student = new Student[1][1];  //initialization
}

@SuppressWarnings("resource")
Scanner s = new Scanner(file);  //used to get the next line from the file
Scanner line; //used to get the next token on a line
int[] sec = {0,0};   //number of students per section
int[] moar; // used to add sections to sec
int k = -1; //index of student within a section
int j = -1; //index of sec that carries the number of students

while(s.hasNextLine())
{
String str = s.nextLine(); //get next line

if(str.length() <= 3)
{
j++; //move to the next section
k=0; //set student index to zero (first student in the class)
if(j>2){
moar = new int[sec.length+1];
for(int ii = 0;ii<sec.length+1;ii++){
moar[ii] = sec[ii]; // add length and copy array
}
sec = moar.clone();
}
sec[j] = Integer.parseInt(str);  // turn the string value of the number of students to an int
student[j] = new Student[sec[j]]; //create a column of length sec[j]
for(int jj = 0; jj<j; jj++){
for(int kk = 0 ; kk<k;kk++){
//System.out.println(student[k][student.length-1].getName());
//System.out.println(student[k][student.length-1].getAverage());
}
}
}
else{
line = new Scanner(str);
while(line.hasNext())
{
name = line.next();
System.out.println(name);

//System.out.println(j + k);
try
{

for(int i =0; i<scores.length ;i++)
{
name = line.next(); //set name equal to the next token
scores[i] = Integer.parseInt(name); //check if name is an int
//System.out.println(scores[i]);
}
}
catch(Exception e)
{
k++; //else increment k and move to the next index for a new student
System.out.println(k); // print the index of the student THIS DOESN'T PRINT AT ALL
while(line.hasNext())
{
System.out.println(name);
}

}

}
student[j][k] = new Student(name, scores);

}

}
System.out.println(student);
}

}

Gold Member
My console output is this:
Johnson
Aniston
Cooper
Gupta
Blair
Clark
Kennedy
Bronson
Sunny
Smith
Diana
[[LStudent;@55f96302

If you remove the comment on the line //System.out.println(scores)
then you get the name followed by the 5 scores for all the students. I also think I'm not creating objects correctly, as I couldn't ever print out their average or name from the actual object itself. I added in a getAverage() and getName() to student in order to be able to do this, but the commented lines
//System.out.println(student[k][student.length-1].getName());
//System.out.println(student[k][student.length-1].getAverage());
didn't print either.
Here is student. There aren't comments, but it's pretty basic.
Java:
public class Student {

String name;
double average;
int[] scores;

public Student(String n, int[] s){
name = n;
scores = s;
calculateAverage();
}

private void calculateAverage(){
int sum =0;
for(int i=0; i<scores.length ; i++){
sum+=scores[i];

}
average = sum/scores.length;

}

if(average%90 <= 10){
}
else if(average%80<10){
}
else if(average%70<10){
}
else if(average%60<10){
}
else{
}
}
public double getAverage(){
return average;
}
public String getName(){
return name;
}

}

And here is my main method

Java:
import java.io.FileNotFoundException;

public class Lab1A {

public static void main(String[] args) throws FileNotFoundException {
ProgressReport pr = new ProgressReport();

}

}

Gold Member
One more thing.
I've tried adjusting the indices to make sure. So I guess the indices on the line
System.out.println(student[jj][kk].getName());
System.out.println(student[jj][kk].getAverage());
with k and student.length-1 rather than jj and kk was more or less a "try it and see what happens" thing. Either way, I get this:
[[LStudent;@55f96302
Which I'm assuming is the address of my array student. This says to me that I'm not actually putting any information into my student array, ever. Couple that with the fact that k never prints tells me that something is going awry in my try-catch block, and I'm having hella issues with this, and I'm not quite sure why.

Thanks for all the help thus far.

Gold Member
By moving all my crap around, I think I have found the problem. I'm never actually "catching" my exception. Now how to fix that, is the problem. Wish I could do my catch before my try haha. =[

Gold Member
Here is my current code:
Java:
import java.io.*;
import java.util.*;

public class ProgressReport{

Student[][] student;  //An array of student objects, the one we care about
Student[][] add;  //A secondary array, used for adding length to the student array (in number of students
Student[][] col;  //A preemptive strike, presumably I will need a third array for columns, currently unused

int[] scores = {0,0,0,0,0};  // Scores for a section
String name = "";  //Name of the student

public ProgressReport() throws FileNotFoundException{
student = new Student[1][1];  //initialization
}

@SuppressWarnings("resource")
Scanner s = new Scanner(file);  //used to get the next line from the file
Scanner line; //used to get the next token on a line
int[] sec = {0,0};   //number of students per section
int[] moar; // used to add sections to sec
int k = -1; //index of student within a section
int j = -1; //index of sec that carries the number of students
String score;

while(s.hasNextLine())
{
String str = s.nextLine(); //get next line

if(str.length() <= 3)
{
j++; //move to the next section
k=-1; //set student index to zero (first student in the class)
if(j>2){
moar = new int[sec.length+1];
for(int ii = 0;ii<sec.length+1;ii++){
moar[ii] = sec[ii]; // add length and copy array
}
sec = moar.clone();
}
sec[j] = Integer.parseInt(str);  // turn the string value of the number of students to an int
student[j] = new Student[sec[j]]; //create a column of length sec[j]
for(int jj = 0; jj<j; jj++){
for(int kk = 0 ; kk<k;kk++){

}
}
}
else{
line = new Scanner(str);
while(line.hasNext())
{
k++;
name = line.next();
System.out.println(k);
//System.out.println(name);

//System.out.println(j + k);
try
{

for(int i =0; i<scores.length ;i++)
{
score = line.next(); //set name equal to the next token
//System.out.println(name);
scores[i] = Integer.parseInt(score); //check if name is an int
//System.out.println(scores[i]);
}
student[j][k] = new Student(name, scores);

System.out.println(student[j][k].getName());
System.out.println(student[j][k].getAverage());
}
catch(Exception e)
{
k++; //else increment k and move to the next index for a new student
System.out.println(k); // print the index of the student THIS DOESN'T PRINT AT ALL
while(line.hasNext())
{
//System.out.println(name);

}

}

}

}

}
System.out.println(student);
}

}

And my output:
Code:
0
Johnson
90.0
1
Aniston
81.0
2
Cooper
82.0
3
Gupta
72.0
4
Blair
52.0
0
Clark
59.0
1
Kennedy
63.0
2
Bronson
90.0
3
Sunny
84.0
4
Smith
75.0
5
Diana
68.0
[[LStudent;@55f96302

Now my question is this:
In hand calculating the average for Johnson, I get 90.6, but the console is printing 90.0. Why?

Actually, all of my averages are truncated...

Last edited:
Gold Member
Ok, I got it. Sorry to keep posting stuff. I needed to cast my scores.length to a double. Seems pretty stupid to me, as a double divided by an int should return a non truncated double, but apparently that is not so in java.

Gold Member
Ok, I got it. Sorry to keep posting stuff. I needed to cast my scores.length to a double. Seems pretty stupid to me, as a double divided by an int should return a non truncated double, but apparently that is not so in java.

Your
Java:
average
variable is taking values integer (from
Java:
sum
) divided by integer from integer array length. So, you essentialy store an integer value to a double variable
Java:
average
and by this you don't get the fractional part.

BiGyElLoWhAt
Gold Member
Yea, I just realized that. Thanks.
Java:1
Me:0
For some reason I had it in my head that sum should have been a double. I have no idea why.

Gold Member
Alright, I apparently had some weird indexing going on. I'm having trouble figuring out what's going on here, as I am not getting any output.
Java:
                while(line.hasNext())
{

name = line.next();
//System.out.println(k);
//System.out.println(name);

//System.out.println(j + k);
try
{

for(int i =0; i<scores.length ;i++)
{
score = line.next(); //set name equal to the next token
//System.out.println(name);
scores[i] = Integer.parseInt(score); //check if name is an int
//System.out.println(scores[i]);
}
//System.out.println("j="+j+" with " +sec[j]);
//System.out.println("k="+k);
student[j][k] = new Student(name, scores);
k++;

System.out.println(student[j][k].getName());
System.out.println(student[j][k].getAverage());

}
catch(Exception e)
{
k++; //else increment k and move to the next index for a new student
//System.out.println(k); // print the index of the student THIS DOESN'T PRINT AT ALL

}

}

The underlying issue is that when I go to generate my report, I'm getting a null pointer exception at index 1.
Java:
    private void generateReport(){

System.out.println("Progress Report \n");
for(int i = 0 ;i<sec.length;i++){
System.out.println("Section " +(i+1));
System.out.println(sec.length);
System.out.println(sec[i] + " i = " +i);
for(int j = 0; j<sec[i];j++){
System.out.println("j = " +j);
System.out.println(student[i][j].getName() + " " + student[i][j].getAverage() + " " + student[i][j].getGrade());

}
}
}

and this gets me:
Code:
Progress Report

Section 1
2
5 i = 0
j = 0
Johnson 90.6 A
j = 1

before throwing the null pointer error.

Gold Member
This seems strange. I just realized that I was being careful enough with my code (while typing out my logic on here) that I don't actually need the try catch block, assuming the file always comes in the correct format (which I will only ever have to read this one file). I got rid of the try catch to try to simplify the program a bit. I also deleted a lot of things to try to clean it up. I think this is peculiar, but hopefully someone can show my why it's not.
Java:
import java.io.*;
import java.util.*;

public class ProgressReport{

Student[][] student;  //An array of student objects, the one we care about
Student[][] add;  //A secondary array, used for adding length to the student array (in number of students
Student[][] col;  //A preemptive strike, presumably I will need a third array for columns, currently unused
int[] sec = {0,0}; //number of students per section
int[] scores = {0,0,0,0,0};  // Scores for a section
String name = "";  //Name of the student

public ProgressReport() throws FileNotFoundException{
student = new Student[1][1];  //initialization
generateReport();
}

@SuppressWarnings("resource")
Scanner s = new Scanner(file);  //used to get the next line from the file
Scanner line; //used to get the next token on a line

int[] moar; // used to add sections to sec
int k = 0; //index of student within a section
int j = -1; //index of sec that carries the number of students
String score;

while(s.hasNextLine())
{
String str = s.nextLine(); //get next line

if(str.length() <= 3)
{
j++; //move to the next section
k=0; //set student index to zero (first student in the class)
if(j>2)
{
moar = new int[sec.length+1];
for(int ii = 0;ii<sec.length+1;ii++){
moar[ii] = sec[ii]; // add length and copy array
}
sec = moar.clone();
}
sec[j] = Integer.parseInt(str);  // turn the string value of the number of students to an int
student[j] = new Student[sec[j]]; //create a column of length sec[j]
for(int jj = 0; jj<=j; jj++){
for(int kk = 0 ; kk<=k;kk++){
}
}
}

else{
line = new Scanner(str);
while(line.hasNext())
{
name = line.next();
for(int i =0; i<scores.length ;i++)
{
score = line.next(); //set name equal to the next token
scores[i] = Integer.parseInt(score); //check if name is an int
}
student[j][k] = new Student(name, scores);

System.out.println(student[j][k].getName());
System.out.println(student[j][k].getAverage());

System.out.println(j+","+k);
k++;
}
}
}

}

private void generateReport(){
System.out.println("Progress Report \n");
for(int i = 0 ;i<=sec.length;i++)
{
System.out.println("Section " +(i+1));
for(int j = 0; j<=sec[i];j++)
{
System.out.println(student[i][j].getName() + " " + student[i][j].getAverage() + " " + student[i][j].getGrade());
}
}
}
}

I get this output:
Code:
Johnson
90.6
A
0,0
Aniston
81.2
B
0,1
Cooper
82.2
B
0,2
Gupta
72.2
C
0,3
Blair
52.2
F
0,4
Clark
59.2
F
1,0
Kennedy
63.4
D
1,1
Bronson
90.0
A
1,2
Sunny
84.8
B
1,3
Smith
75.4
C
1,4
Diana
68.8
D
1,5
Progress Report

Section 1
Johnson 90.6 A
at ProgressReport.generateReport(ProgressReport.java:117)
at ProgressReport.<init>(ProgressReport.java:18)
at Lab1A.main(Lab1A.java:6)
Everything works greatly as I'm filling the array initially. I get everything exactly as it should be, including the indices of the student. However, I am getting null pointer exception when I try to access students[0][1].getName(). Not 0,0 . Only for this 0,1. However, if you look up, I am filling students[0][1] with a student with name Aniston, average 81.2, grade B.

Gold Member
... It's filling properly, but somewhere I'm overriding (0,1)-(0,5)
via the variable explorer and some breakpoints...

Gold Member
Ok, I found it. I was resetting k to zero, and then cloning, for kk < k, so switching to kk <sec[jj] fixed my issue.

Gold Member
On a somewhat unrelated note, does anyone know how I can swap the position of "outline" and "variables" in eclipse Neon? Currently, outline appears on the rhs, and variables likes to be on the top. I would rather have variables on the side, so I can minimize outline and have my actual code be large vertically, on the LHS and my variables large on the RHS.