java array passing, I keep getting the last array everywhere - java

I am having a problem in this code. what i am trying to do is read a file and store a studentID and score into an array of scores into the scores property of a student object, but I keep getting the last scores only when I print. Here is the code. can you tell me if my setter property is a correct way of assigning an array in the student class? the problem is the last line of the score file is stored in every array even though when I debug it I see the score array being passed and the studentID array works fine.
import lab6.*;//importing the necessary classes
public class Main
{
public static void main(String[] args)
{
Student lab6 [] = new Student[40];
//Populate the student array
lab6 = Util.readFile("studentScores.txt", lab6);
lab6[4].printStudent();
}
}
The student class------------------------------------
package lab6;
public class Student
{
private int SID;
private int scores[] = new int[5];
//write public get and set methods for SID and scores
public int getSID()
{
return SID;
}
public void setSID(int SID)
{
this.SID = SID;
}
public int[] getScores()
{
return scores;
}
public void setScores(int scores[])
{
this.scores = scores;
}
//add methods to print values of instance variables.
public void printStudent()
{
System.out.print(SID);
System.out.printf("\t");
for(int i = 0; i < scores.length; i++)
{
System.out.printf("%d\t", scores[i]);
}
}
}
the util class --------------------------------------------------------------------
import java.io.*;
import java.util.StringTokenizer;
//Reads the file and builds student array.
//Open the file using FileReader Object.
//In a loop read a line using readLine method.
//Tokenize each line using StringTokenizer Object
//Each token is converted from String to Integer using parseInt method
//Value is then saved in the right property of Student Object.
public class Util
{
public static Student [] readFile(String filename, Student [] stu)
{
try {
String line[] = new String[40];//one line of the file to be stored in here
StringTokenizer stringToken;
int studentID;//for storing the student id
int[] studentScoreArray = new int[5];//for storing the student score
FileReader file = new FileReader(filename);
BufferedReader buff = new BufferedReader(file);
boolean eof = false;
int i = 0;
buff.readLine();//used this to skip the first line
while (!eof) //operation of one line
{
line[i] = buff.readLine();
if (line[i] == null)
eof = true;
else //tokenize and store
{
stringToken = new StringTokenizer(line[i]);
String tokenID = stringToken.nextToken().toString();//for storing the student id
studentID = Integer.parseInt(tokenID);
stu[i] = new Student();//creating student objects
stu[i].setSID(studentID);//stored in student object
//now storing the score-------------------------------------------------
int quizNumberCounter = 0;
while (stringToken.hasMoreTokens())
{
String tokens = stringToken.nextToken().toString();
studentScoreArray[quizNumberCounter] = Integer.parseInt(tokens);//converting and storing the scores in an array
quizNumberCounter++;//array progression
}
stu[i].setScores(studentScoreArray);//setting the score(passing it as an array)
//-----------------------------------------------------------------------
}
i++;
}
buff.close();
} catch (IOException e) {
System.out.println("Error -- " + e.toString());
}
return stu;
}
/*
StringTokenizer st = new StringTokenizer("this is a test");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
//How to convert a String to an Integer
int x = Integer.parseInt(String) ;*/
}
Sample file Structure -------------------------------------------------------
4532 011 017 081 032 077

The issue lies within the line
int[] studentScoreArray = new int[5];
You'll have to move this one inside your student loop and initialize the array per student. Otherwise you are reusing the same array (i.e. memory) for all students and you are overwriting scores over and over again.
// int[] studentScoreArray = new int[5]; // <= line removed here!!!
...
while (!eof) //operation of one line
{
line[i] = buff.readLine();
if (line[i] == null)
eof = true;
else //tokenize and store
{
int[] studentScoreArray = new int[5]; // <= line moved over to here!!!
...
}
}

I havent tested the code with my suggestion, but take a look at:
int[] studentScoreArray = new int[5];
You create this once and once only for the whole file.
A simple and easy fix is to do it for every new line read instead.
like this :
int[] studentScoreArray = new int[5];
int quizNumberCounter = 0;
while(..) { ...}

One reason you may only being seeing one line of results is that you are only printing one line of results:
lab6[4].printStudent();
You will need to change this to loop through the array if you want to see all the results:
foreach (Student student : lab6)
{
student.printStudent();
}
On a side note, your array should probably be called something like students instead of lab6. Also it is idiomatic in java to declare arrays using Type[] identifier rather than Type identifier [].
DISCLAIMER: There may be other stuff wrong, I didn't read all the hundreds of lines posted!

Related

java - read file and create array

I have to follow a specific format and use scanner. I know there are better methods, but this is a requirement and I am new to java and trying to figure this out. There is a file with customer name, birth date, and other information. I need to count the number of entries in the file, then the file needs to create an array based on the number of file entries and convert the array to a string array. There is more code I need to do, but I am stuck on this part. The try/catch has to be used.
public class Customers {
//////// MAIN ////////
public static void main(String[] args) {
File file = new File("customers.txt");
int numEntries = countCustomers(file);
Person[] customers = readIntoArray(file, numCustomers);
int min = locateBirthdate(customers);
System.out.println("Birthdays this month: " + customer[mon].getBirthdate());
}
//* Counts customers in the file.//
public static int countCustomers(File f) {
int i = 0;
try {
Scanner scan = new Scanner(f);
while (scan.hasNextLine()) {
i++;
scan.nextLine();
}
} catch (Exception e) {
System.out.println("Check filename.");
}
return i;
}
//read data into array and convert into string array
public static Customer[] readIntoArray(File f, int num) {
//num = countCustomers(f);
num = 0;
try {
Scanner input = new Scanner(f);
Customer[] birth = new Customer[num];
String[] strBirth = new String[num];
while (num < countCustomers(f)) {
strBirth[num] = input.nextLine();
birth[num] = makeCustomer(strBirth[num]);
num++;
System.out.println(num);
}
} catch (Exception e) {
System.out.println("Error");
}
return null;
Ok. I have several comments.
First - do you really need 'strBirth' array? Looks like you only write elements but not read from the array.
Second - 'readIntoArray' method always returns null.
Also, you count customers twice, but only one is enough.
Then, do you really need an array with customers? Since you use an array, you need to know exactly the count of customers and therefore you need to scan the file twice. If you use ArrayList, you need to scan file only one time.
I have fixed the issues in the code below.
public class Customers {
//////// MAIN ////////
public static void main(String[] args) {
File file = new File("customers.txt");
Person[] customers = readIntoArray(file, numCustomers);
int numEntries = customers.length;
int min = locateBirthdate(customers);
System.out.println("Birthdays this month: " + customer[mon].getBirthdate());
}
public static Person[] readIntoArray(File f, int num) {
List<Customer> customers = new ArraList<>();
try {
Scanner input = new Scanner(f);
String[] strBirth = new String[num];
while (scan.hasNextLine()) {
customers.add(makeCustomer(scan.nextLine()));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return customers.toArray(Person[]::new);
}

Returning and displaying contents of ArrayList in different class?

I'm working on a project where I will tally a Student's choices and add them to a count array (still working on this part). For now, I'm trying to retrieve the choices that have been sent and added to a Student ArrayList in my Student class.
Student class:
public class Students {
private String name;
private ArrayList<Integer> choices = new ArrayList<Integer>();
public Students(){
name = " ";
}
public Students(String Name){
name = Name;
}
public void setName(String Name){
name = Name;
}
public String getName(){
return name;
}
public void addChoices(int Choices){
choices.add(Choices);
}
public ArrayList<Integer> getChoices(){
return choices;
}
Here is my main driver class:
public class P1Driver {
public static void main(String[] args) throws IOException{
ArrayList<Students> students = new ArrayList<Students>();
String[] choices = new String[100];
int[] count;
Scanner scan1 = new Scanner(new File("Choices.txt"));
Scanner scan2 = new Scanner(new File("EitherOr.csv"));
// Scan the first file.
int choicesIndex = 0;
while(scan1.hasNextLine()){
String line = scan1.nextLine();
choices[choicesIndex] = line;
choicesIndex++;
}
scan1.close();
// Scan the second file.
int studentIndex = 0;
while(scan2.hasNextLine()){
String line = scan2.nextLine();
String [] splits = line.split(",");
students.add(new Students(splits[0]));
for(int i = 1; i < splits.length; i++){
students.get(studentIndex).addChoices(Integer.parseInt(splits[i]));
}
studentIndex++;
}
scan2.close();
// Instantiate and add to the count array.
int countIndex = 0;
for(int i = 0; i < students.size(); i++){
if(students.get(i).getChoices(i) == -1){
}
}
The last part is where I am now. It's nowhere near done obviously (I'm right in the middle of it) but during my construction of a for loop to get the choices from the students, I'm getting an error that says, "The method getChoices() in the type Students is not applicable for the arguments (int)." Can someone explain what this means, where me error is, and possibly how to fix it? Thanks all.
getChoices(int i) is not a method you've defined.
if(students.get(i).getChoices(i) == -1){
}
getChoices() returns a list, so you can just use the get method on the list:
if(students.get(i).getChoices().get(i) == -1){
}
Alternatively, make a getChoice method:
public Integer getChoice(int i){
return choices.get(i);
}
Have you tried getChoices()[i] instead of getChoices(i)

Why is this "not a statement" in java?

I am very new to Java. My current program loops through a block that asks for users input in the console until the value they type equals done. I want to store each value the user types in an array that is a class property. When I try to append this array, I get an error that says Error:(59, 18) java: not a statement. My code is below. I will point out the line that the error occurs on inside the code. Thanks for your time!
package com.example.java;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Welcome to the musical key calculator!");
System.out.println("Enter your notes one at a time.");
System.out.println("Use uppercase letters A-G and # for sharp and b for flat.(Ex. Eb)");
System.out.println("Remember that E# and B# do not exist in music!");
System.out.println("When you have entered all of your notes, type 'done'");
System.out.println("------------------------------------------------------------------");
boolean finished = false;
Scale YourScale = new Scale();
while(finished == false) {
System.out.print("Enter a note: ");
String note = scanner.nextLine();
if (note == "done'") {
finished = true;
} else {
YourScale.addNote(note);
}
}
if(finished == true){
StringBuilder output = new StringBuilder("Your notes are ");
String[] completedNotes = YourScale.notes;
for (int i = 0; i < completedNotes.length; i++) {
output.append(completedNotes[i] + " ");
}
}
}
public static class Scale {
public String[] notes = {};
public void addNote(String note){
notes[] = note; //Error occurs here.
}
}
}
Java arrays are fixed length, and that isn't how you create (or populate an array). I would prefer to use a Collection like,
public List<String> notes = new ArrayList<>();
public void addNote(String note){
notes.add(note);
}
But, you could use Arrays.copyOf(T[], int) and something like
public String[] notes = new String[0];
public void addNote(String note){
int len = notes.length;
notes = Arrays.copyOf(notes, len + 1);
notes[len] = note;
}
Finally, you do not test String equality with ==
if (note == "done'") {
should be something like
if (note.equals("done")) {
notes is a String array, which means it has many String objects inside. Also you initialize it to an empty array. Arrays should have a fixed size.
//Declare a variable notes, and initialize it as an empty array?
public String[] notes = {};
public void addNote(String note)
{
//This doesn't make sense in java - it's syntax is wrong
notes[] = note;
}
If you want to use arrays this is an example:
//Declare a variable notes, and initialize it as an array of
//specific size (I used 5 as example)
public String[] notes = new String[5];
public void addNote(String note)
{
//Here you should have some short of counter that counts in which
// position of the array you will save 'note' or just run a 'for'
//loop and the first element that is not initialized can get the note
for (int i = 0; i < notes.length; i++)
if (notes[i] == null)
{
notes[i] = note;
break;
}
}
Although this method allows you to save a fixed size, which is not desirable in your case, but nevertheless it uses Array and can help you understand how to use them.
If you want to implement it properly you should use an ArrayList. An ArrayList is an array where you can add new elements and remove them. You can find plenty of documentation online of how to use them.
You are trying to assign a String to a String array. You probably intended to add it to the array.

Task dealing with sorting 2d array

I have been assigned a task that requires me to utilise a 2D Array. I have to read in a file and export it to a 2D array. I can only have a single method but I am unable to sort the array correctly. I am supposed to sort the data in 3 ways (alphabetically by name and with scores highest to lowest; highest to lowest scores for each student and highest to lowest by the average of 3 scores.) So far I have
import java.util.*;
import java.io.*;
public class ScoreSorter {
public static void main(String[] args) {
int student_num = 30;
String[][] DataInTableArr = new String[30][6];
try {
BufferedReader ReadIn = new BufferedReader(new FileReader("classZ.csv"));
for (int i = 0; i < 30; i++) {
String DataIn = ReadIn.readLine();
String[] DataInArr = DataIn.split(",");
DataInTableArr[i][0] = DataInArr[0];
DataInTableArr[i][1] = DataInArr[1];
DataInTableArr[i][2] = DataInArr[2];
DataInTableArr[i][3] = DataInArr[3];
int temptest1 = Integer.parseInt(DataInArr[1]);
int temptest2 = Integer.parseInt(DataInArr[2]);
int temptest3 = Integer.parseInt(DataInArr[3]);
}
} catch (Exception e) {
System.out.println("Whoops, you messed up, RESTART THE PROGRAM!!!!!");
}
}
}
I have no idea as to how to solve the rest of the task... I would appreciate if someone could tell me of the most efficient way and perhaps an example...
One plausible way is to create a Student class which implements Comparable interface, with the following members:
String name;
int scoreOne;
int scoreTwo;
int scoreThree;
compareTo(Student s) { //implement the comparison following 3 criteria you mentioned }
And, read the files row by row, for each row we create a Student object, and put all rows in a TreeSet. In this way, the TreeSet together with the compareTo method will help us sort the Students automatically.
Finally, iterate the sorted TreeSet to fill up the 2D array.
import java.util.*;
import java.io.*;
public class ScoreSorter {
public static void main(String[] args) {
int student_num = 30;
String[][] DataInTableArr = new String[30][6];
try {
BufferedReader ReadIn = new BufferedReader(new FileReader("classZ.csv"));
for (int i = 0; i < 30; i++) {
String DataIn = ReadIn.readLine();
String[] DataInArr = DataIn.split(",");
DataInTableArr[i][0] = DataInArr[0];
DataInTableArr[i][1] = DataInArr[1];
DataInTableArr[i][2] = DataInArr[2];
DataInTableArr[i][3] = DataInArr[3];
int temptest1 = Integer.parseInt(DataInArr[1]);
int temptest2 = Integer.parseInt(DataInArr[2]);
int temptest3 = Integer.parseInt(DataInArr[3]);
}
/*Code To be Inserted Here*/
} catch (Exception e) {
System.out.println("Whoops, you messed up, RESTART THE PROGRAM!!!!!");
}
}
}
If there are 6 columns such that First is name and the other 3 are scores then what does other 2 columns contain?? I ignore your array declaration :
String[][] DataInTableArr = new String[30][6];
and assume it to be 30x4 array
String[][] DataInTableArr = new String[30][4];
Logic for sorting Alphabetically
if(DataInTableArr[i][0].compareTo(DataInTableArr[i+1][0])){
/* Sorting Name of adjacent rows*/
String temp = DataInTableArr[i][0];
DataInTableArr[i][0] = DataInTableArr[i+1][0];
DataInTableArr[i+1][0] = temp;
/*Sorting the three marks similarly*/
temp = DataInTableArr[i][1];
DataInTableArr[i][1] = DataInTableArr[i+1][1];
DataInTableArr[i+1][1] = temp;
temp = DataInTableArr[i][2];
DataInTableArr[i][2] = DataInTableArr[i+1][2];
DataInTableArr[i+1][2] = temp;
temp = DataInTableArr[i][3];
DataInTableArr[i][3] = DataInTableArr[i+1][3];
DataInTableArr[i+1][3] = temp;
}
Put the above code in bubble sorting algorithm i.e. 2 loops.
Logic for sorting according to highest marks
In this case you have to find the highest marks in all three subjects of each DataInTableArr[i] and then compare the highest marks with that of next row.
Logic for sorting according to Average marks
Calculate the average of each i'th row as
(Integer.parseInt(DataInTableArr[i][1]) + Integer.parseInt(DataInTableArr[i][2]) + Integer.parseInt(DataInTableArr[i][3]))/3
and compare it with [i+1] th rows average.(same formula just replace [i] with [i+1])

Null pointer with 2d arrays and objects

Hello I am making a project of multiple classes that creates a progress report. However I am testing out methods and am not yet complete with the project and came across a null pointer exception. Take a look at the code and see if you can help me out please. Keep in mind all methods aren't finished just trying to focus on my problem first. I also have a separate driver file that i do not find relevant to post, unless needed otherwise.
Student class:
public class Student {
private String name;
private char grade;
private double average;
private int[] scores = new int[5];
// Constructor
public Student() {
this.name = name;
this.grade = grade;
this.average = average;
this.scores = scores;
}
// Get the Name.
public String getName() {
return name;
}
// Set the Name.
public void setName(String name) {
this.name = name;
}
// Get the Grade.
public char getGrade() {
return grade;
}
// Set the Grade.
public void setGrade(char grade) {
this.grade = grade;
}
// Get the Average.
public double getAverage() {
return average;
}
// Set the Average.
public void setAverage(double average) {
this.average = average;
}
// Get the Scores.
public int[] getScores() {
return scores;
}
// Set the Scores.
public void setScores(int[] scores) {
this.scores = scores;
}
// Determine the average of the five test scores for each student
public void calculateAverage(){
}
public void calculateGrade(){
}
}
ProgressReport class (where im getting the null pointer exception):
public class ProgressReport {
// Create array to hold sections and students.
Student[][] sectionArray = new Student[2][];
// Constructor.
public ProgressReport() {
}
// Get sectionArray.
public Student[][] getSectionArray() {
return sectionArray;
}
// Set sectionArray.
public void setSectionArray(Student[][] sectionArray) {
this.sectionArray = sectionArray;
}
// Read the input file.
public void readInputFile() throws FileNotFoundException{
String line;
int studentNo;
// Open file
File inFile = new File("file.in");
// Create scanner for reading.
Scanner scanner = new Scanner(inFile);
// While inFile has more lines.
while(scanner.hasNext()){
// Read the next line.
line = scanner.nextLine();
// Trim line.
line = line.trim();
//Parse line into int.
studentNo = Integer.parseInt(line);
// For the number of students in section 1 extract data.
for(int i = 0; i<= studentNo; i++){
//Create new student.
sectionArray[0][i] = new Student(); **THIS IS WHERE I GET NULL POINTER EXCEPTION**
// Read next line.
line = scanner.nextLine();
// Create String Tokenizer using a space as the delimiter.
StringTokenizer strTokenizer = new StringTokenizer(line," ");
// While the String Tokeizer has more tokens get data.
while(strTokenizer.hasMoreTokens()){
// Extract name
String name = strTokenizer.nextToken();
// Set name
sectionArray[0][i].setName(name);
int[] scores = new int[5];
// Extract scores.
int score1 = Integer.parseInt(strTokenizer.nextToken());
int score2 = Integer.parseInt(strTokenizer.nextToken());
int score3 = Integer.parseInt(strTokenizer.nextToken());
int score4 = Integer.parseInt(strTokenizer.nextToken());
int score5 = Integer.parseInt(strTokenizer.nextToken());
//Put scores in scores array.
scores[0] = score1;
scores[1] = score2;
scores[2] = score3;
scores[3] = score4;
scores[4] = score5;
// Set scores.
sectionArray[0][i].setScores(scores);
}
}
}
}
// Generate a report.
public void generateReport(){
System.out.println("Progress Report\n");
System.out.println("Section 1");
System.out.println(sectionArray[0][0].getName());
}
// Sort by name.
public void sortByName(){
}
// Binary search.
public Student binarySearch(int section, String searchName){
return null;
}
}
I'm not asking anyone to finish my work, just explain why I am getting a null pointer exception please.
You need to initialize the second dimension once you know your number of Students as
studentNo = Integer.parseInt(line);
// initialize the Array
sectionArray[0] = new Student[studentNo];
// For the number of students in section 1 extract data.
for(int i = 0; i<= studentNo; i++){
You've always used your sectionArray as sectionArray[0][*]. I'm not sure if you actually need the array to be two-dimensional. Initializing it as new Student[2][]; suggests that you would be using sectionArray[1][*] as well at some point of time.
If you do that later on; you would need to initialize sectionArray[1] as well.
If you do something like this
String[][] array = new String[2][];
it would create one array that will have two null elements, so it is the same as
String[][] array = {null,null};
and since you are invoking sectionArray[0][i] on such array it is the same as invoking null[i] which throws NPE.
You need to specify both dimensions like: Student[][] sectionArray = new Student[2][2]; or initialize the second dimension like this: sectionArray[0] = new Student[students]; and sectionArray[1] = new Student[students];.
Well You are using array of array here for Student Class.
For each array of (array of array) you need to initiate each array with its required number
of elements .
Here :
Before this line... where you are getting Null pointer Exception,
sectionArray[0][i] = new Student();
you need to initiate the array sectionArray[0] with new keyword like this.
sectionArray[0]= new Student[studentNo]; // add this line to you code
then the code you have used will come.

Categories

Resources