I have my code working right, the only problem is that my output isn't correct because I can't find the right place to set the array of numbers back to zero. The basis of the programs is to take in data that contains names with corresponding grades. My output should follow this criteria:
Alice [87, 99, 96, 99, 86, 96, 77, 95, 70, 88]
Name: Alice
Length: 10
Average: 89.30
Median: 91.5
Maximum: 99
Mininum: 70
I get the first person's results correct, however, the ones that follow are incorrect because they contain all of the values being read in for every person. So, the next person will have "Alice's" grades plus their own when my code performs operations on the array for that person. I have two programs, the first is the main program that reads the data in and calls the methods to print and operate. The second is the class with all the methods that perform the operations.
This is the main program:
public class Lab2 {
public static void main(String[] args) {
Scanner in = null; //initialize scanner
ArrayList<Integer> gradeList = new ArrayList<Integer>(); //initialize gradeList
//grab data from data.txt
try {
in = new Scanner(new File("data.txt"));
} catch (FileNotFoundException exception) {
System.err.println("failed to open data.txt");
System.exit(1);
}
//while loop to grab tokens from data
while (in.hasNext()) {
String studentName = in.next(); //name is the first token
while (in.hasNextInt()) { //while loop to grab all integer tokens after name
int grade = in.nextInt(); //grade is next integer token
gradeList.add(grade); //adding every grade to gradeList
}
//grab all grades in gradeList and put them in an array to work with
int[] sgrades = new int[gradeList.size()];
for (int index = 0; index < gradeList.size(); index++) {
sgrades[index] = gradeList.get(index); //grade in gradeList put into grades array
}
Grades myGrade = new Grades(studentName,sgrades);
testGrades(myGrade);
sgrades = null;
}
}
public static void testGrades(Grades grades) {
System.out.println(grades.toString());
System.out.printf("\tName: %s\n", grades.getName());
System.out.printf("\tLength: %d\n", grades.length());
System.out.printf("\tAverage: %.2f\n", grades.average());
System.out.printf("\tMedian: %.1f\n", grades.median());
System.out.printf("\tMaximum: %d\n", grades.maximum());
System.out.printf("\tMininum: %d\n", grades.minimum());
grades = null;
}
}
I've tried adding place to erase the values of the array for the next person by setting it to null. I've had no luck with this.
This is the next program, which contains the methods.
public class Grades {
private String studentName; // name of course this GradeBook represents
private int[] grades; // array of student grades
/**
* #param studentName The name of the student.
* #param grades The grades for the student.
*/
public Grades(String name, int[] sgrades) {
studentName = name; // initialize courseName
grades = sgrades; // store grades
} // end two-argument GradeBook constructor
/**
* Method to convert array to a string and print.
*
* #return The name of the student with array of grades.
*/
public String toString() {
return (String) studentName + " " + Arrays.toString(grades);
}
/**
* One-argument constructor initializes studentName.
* The grades array is null.
*
* #param name The name of the student.
*/
public Grades(String name) {
studentName = name; // initialize courseName
} // end one-argument Grades constructor
/**
* Method to set the student name.
*
* #return The name of the student.
*/
public String getName() {
return studentName;
} // end method getCourseName
/**
* Method to set the length of the amount of grades.
*
* #return Number of grades for student.
*/
public int length() {
return grades.length;
}
/**
* Determine average grade for grades.
*
* #return the average of the grades.
*/
public double average() {
double total = 0; // initialize total
double average = 0.0;
// sum grades for one student, while loop
int index = 0;
while (index < grades.length) {
int grade = grades[index]; // get grade at index
total += grade;
index++; // need to increment
}
average = total / grades.length;
// return average of grades
return (double) average;
} // end method getAverage
/**
* Determine median grade for grades.
*
* #return the median of the grades.
*/
public double median() {
Arrays.sort(grades); //sort grades array
double median = 0.0;
if (grades.length%2 == 0) //checks to see if amount of grades is even/odd
//this is median if list of grades is even
median = ((double)grades[grades.length/2-1] + (double)grades[grades.length/2])/2;
else
//this is median if list of grades is odd
median = (double) grades[grades.length/2];
return (double) median;
}
/**
* Find minimum grade.
*
* #return the minimum grade.
*/
public int minimum() {
int lowGrade = grades[0]; // assume grades[0] is smallest
// loop through grades array, for loop
for (int index = 0; index < grades.length; index++) {
int grade = grades[index]; // get grade at index
// if grade lower than lowGrade, assign it to lowGrade
if (grade < lowGrade)
lowGrade = grade; // new lowest grade
} // end for
return lowGrade; // return lowest grade
} // end method getMinimum
/**
* Find maximum grade.
*
* #return the maximum grade.
*/
public int maximum() {
int highGrade = grades[0]; // assume grades[0] is largest
// loop through grades array, for-each loop
for (int grade : grades) {
// if grade greater than highGrade, assign it to highGrade
if (grade > highGrade)
highGrade = grade; // new highest grade
} // end for
return highGrade; // return highest grade
} // end method getMaximum
}
My main question is, how can I "refresh" the array for every new student that I read in?
You're looking for gradeList.clear(). But why are you copying everything from gradeList to sgrades? Seems kind of redundant.
Related
I want my array of students to have their name and grade associated. So when I call on them after the fact I can display the top two performing students. This is homework So I don't need to have the whole code completed but I would like some help with making sure the inputs are properly stored. Right now my variables are x and i, x being the number of students, and i being the counter. Again my issues are with associating the grades of the students inputted with the names. I hope there is enough information.
import java.util.Scanner;
public class Q3 {
public static void main(String[] args) {
int x = 0;
double average = 0;
int i = 0;
Scanner in = new Scanner(System.in);
System.out.println("Please eneter how many students you have: ");
x = in.nextInt();
int students = 0;
int sum = 0;
int grades[] = new int[x];
String[] names = new String[x];
for(i = 0; i <= x; i++) {
System.out.println("Please enter student name: ");
String name = in.nextLine();
names[i] = name;
System.out.println("Grade: ");
int grade = in.nextInt();
grades[i] = grade;
students++;
sum += grade;
x++;
}
if(students>0) {
average = (double) sum/students;
}
System.out.println("The average is " + average);
System.out.println("There are " + students + " students");
System.out.println("The top two students are: " + grades);
}
}
The problem with your current code is that the for loop will never end, as you keep increasing the value of x, which is also used in the end condition.
Here are some suggestions:
Just store the number of students when you read it and remove the x variable:
int students = in.nextInt();
int grades[] = new int[students ];
String[] names = new String[students ];
Then read in this number of sudents:
for(i = 0; i < students; i++) {
To find the top two students you'd use the following logic (assumes 2 or more students)
if grade[0] >= grade[1]
max1 = 0
max2 = 1
else
max1 = 1
max2 = 0
for i from 2 to students-1
if grade[i] >= grade[max1]
max2 = max1
max1 = i
else if grade[i] > grade[max2]
max2 = i
The top two students are then at positions max1 and max2 in the names and grades array.
Probably overkill, but maybe someone will find it useful.
I store all the students in a TreeSet. I assume that each student has a unique name. I use a special Comparator to sort the students in the TreeSet according to their grades. A descending Iterator of the TreeSet will return the students from highest grade to lowest grade, so the first two items returned by this Iterator are the top two students.
import java.util.Comparator;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;
/**
* A student name and her grade.
*/
public class StudentGrade {
/** Name of student. */
private String studentName;
/** Grade for this student. */
private int studentGrade;
/**
* Creates and returns instance of this class.
*
* #param name - student name
* #param grade - student grade
*/
public StudentGrade(String name, int grade) {
studentName = name;
studentGrade = grade;
}
/**
* #return Student's name.
*/
public String getStudentName() {
return studentName;
}
/**
* #return Student's rgade.
*/
public int getStudentGrade() {
return studentGrade;
}
/**
* Two instances of this class are equal if they both have the same name.
*/
#Override // java.lang.Object
public boolean equals(Object obj) {
boolean isEqual = false;
if (obj != null) {
Class<?> objClass = obj.getClass();
if (objClass.equals(getClass())) {
StudentGrade other = (StudentGrade) obj;
isEqual = studentName.equals(other.getStudentName());
}
}
return isEqual;
}
#Override // java.lang.Object
public int hashCode() {
return studentName.hashCode();
}
#Override // java.lang.Object
public String toString() {
return String.format("%s [%d]", studentName, studentGrade);
}
/**
* Start here.
*/
public static void main(String[] args) {
// Stores all student grades, sorted by grade in ascending order.
TreeSet<StudentGrade> studentSet = new TreeSet<>(new StudentGradeComparator());
Scanner in = new Scanner(System.in);
System.out.print("Please enter how many students you have: ");
int students = in.nextInt();
int index = students;
int sum = 0;
while (index > 0) {
// make sure we consume the newline character since 'nextInt()' does not
in.nextLine();
System.out.print("Enter student name: ");
String name = in.nextLine();
System.out.printf("Enter grade for %s: ", name);
int grade = in.nextInt();
sum += grade;
StudentGrade sg = new StudentGrade(name, grade);
studentSet.add(sg);
index--;
}
double average;
if (students > 0) {
average = (double) sum / students;
}
else {
average = 0.0d;
}
System.out.println("The average is " + average);
String verb = students == 1 ? "is" : "are";
String plural = students == 1 ? "" : "s";
System.out.printf("There %s %d student%s.%n", verb, students, plural);
if (students > 1) {
Iterator<StudentGrade> iter = studentSet.descendingIterator();
System.out.printf("The top two students are: %s, %s%n", iter.next(), iter.next());
}
}
}
/**
* Compares 'StudentGrade' instances according to their grades.
*/
class StudentGradeComparator implements Comparator<StudentGrade> {
/**
* Returns a positive number if 'sg1' grade is larger than that of 'sg2'.
* Returns a negative number if 'sg1' grade is less than that of 'sg2'.
* Returns zero if 'sg1' grade is equal to 'sg2' grade.
*/
#Override
public int compare(StudentGrade sg1, StudentGrade sg2) {
if (sg1 == null) {
if (sg2 != null) {
return -1;
}
else {
return 0;
}
}
else {
if (sg2 == null) {
return 1;
}
else {
return sg1.getStudentGrade() - sg2.getStudentGrade();
}
}
}
}
Here is a sample run:
Please enter how many students you have: 3
Enter student name: George
Enter grade for George: 70
Enter student name: Diego
Enter grade for Diego: 90
Enter student name: Edson
Enter grade for Edson: 65
The average is 75.0
There are 3 students.
The top two students are: Diego [90], George [70]
I have a program that takes students' names and grades as user input and then performs some operations on them, which are irrelevant for the scope of the question. The code is as follows:
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
public class Student {
// Four attributes that define Student
private String name;
private double points;
private int startYear;
private int[] grades;
public Student(String name, double points, int startYear, int[] grades) {
this.name = name;
this.points = points;
this.startYear = startYear;
this.grades = grades;
}
//Constructor. Everyone starts with 0 points and this year
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); //Create scanner
System.out.println("Please enter the number of students:");
int count = sc.nextInt(); // Number of students
System.out.println("Please enter the number of grades:");
int count1 = sc.nextInt(); // Number of grades
Student students[] = new Student[count]; // Create array of student objects based on previously entered value
int[] temp = new int[count1]; // Temporary array for storing grades entered
for (int i = 1; i < count + 1; i++) {
System.out.println("Please enter the name of student " + i);
String name = sc.next();
students[i - 1] = new Student(name,0.0,2018,temp); // Creating student object
System.out.println("Please enter grades of " + name);
for (int k = 0; k < count1; k++) {
int personal_grades = sc.nextInt();
temp[k] = personal_grades; //filling the temporary array
//System.out.println(grades.length); //for debugging
}
students[i - 1].setGrades(temp); //transferring from temporary array to student object array
students[i-1].printGrades();
}
System.out.println((students[0].name));
System.out.println((students[1].name));
System.out.println(Arrays.toString(students[0].grades));
System.out.println(Arrays.toString(students[1].grades));
for(int i = 0; i < count; i++) {
System.out.println("Grades of " + students[i].name + " are:");
//students[i].printGrades();
}
for(int i = 0; i < count; i++) {
System.out.println("Average of " + students[i].name + " is:");
// students[i].average();
}
int passed=0;
for(int i = 0; i < count; i++) {
if(students[i].average()>5.5)
{
passed++;
}
}
System.out.println(passed+" students passed!");
}
public void setGrades(int[] temp) {
this.grades = temp;
}
public int[] getGrades() {
return grades;
}
public void printGrades() {
System.out.println(Arrays.toString(grades));
}
public float average (){
int k = 0;
int sum=0;
float average=0;
while (k < this.grades.length) {
sum=sum+this.grades[k];
k++;
}
average = sum/(float)this.grades.length;
System.out.println(average);
return average;
}
}
The problem I am having with the code is as follows: the setter method appears to set the values for all of the objects that were ever created. Take this test run as an example:
You can see that the grades for the last student entered appear in every student's record. I have debugged and found that it is the setGrades method that causes this. However, I am using the this keyword - why does it set the value for all the objects then?
You need to move the
int[] temp = new int[count1]; // Temporary array for storing grades entered
inside the outer for loop, otherwise all created Students will have a reference to same grades array and all will end up with the grades of the last student.
It's because you are using the same array for all the grades of everyone.
Moving
temp = new int[count1]; inside the first loop should fix it
Note how both Student's constructor and Student::setGrades() get grades by reference.
This means that for each Student's instance, its grades field points to the parameter that was received during its initialization.
However, you only initialize temp once and therefore all the instances point to the same grades array. Once this array is changed, calling student.printGrades() will print the shared array's contents.
This can be solved by initializing temp on every iteration, before creating a new Student instance; Or by copying the array by value inside setGrades() method:
public void setGrades(int[] temp) {
this.grades.clone(temp);
}
Move the array (temp) holding the grades inside the loop where you create individual Students
for (int i = 1; i < count + 1; i++) {
...
int[] temp = new int[count1]; //The array holding the grades must be *specific* for each student
students[i - 1] = new Student(name, 0.0, 2018, temp); // Creating student object
...
students[i - 1].setGrades(temp); //transferring from temporary array to student object array
students[i - 1].printGrades();
}
In your original code, you are using just one array i.,e temp was pointing to the same array all the time. After you finish initializing the first Student, when you loop populating the grades for the second student, you are mutating (or modifying) the same grades array created for the first student.
I have an assignment for my class that goes like this:
"Write a Payroll class that uses the following arrays as fields:
employeeID - An array of seven integers to hold employee identification numbers.
The array should be initialized with the following numbers:
5658845 4520125 7895122 8777541 8451277 1302850 7580489
hours - An array of seven integers to hold the number of hours worked by each employee.
payRate - An array of seven doubles to hold each employee's hourly pay rate.
wages - An array of seven doubles to hold each employee's gross wages.
The class should relate the data in each array through the subscripts.
For example, the number in element 0 of the hours array should be the number of hours worked by the employee
whose identification number is stored in element 0 of the employeeID array.
That same employee's pay rate should be stored in element 0 of the payRate array.
In addition to the appropriate accessor and mutator methods,
the class should have a method that accepts an employee's identification number
as an argument and returns the gross pay for that employee.
I'm having trouble passing values from the program I created. Here is the class:
public class moduleArray2
{
final int NUM_EMPLOYEES = 7;
int[] employeeID = {5658845, 4520125, 7895122, 8777541, 8451277, 1302850, 7580489};
int[] hours = new int[NUM_EMPLOYEES];
double[] payRate = new double[NUM_EMPLOYEES];
double[] wages = new double[NUM_EMPLOYEES];
int employee = 0;
double wage = 0;
// setHours method
public void setHours(int[] time)
{
time = hours;
}
// setPayRate method
public void setPayRate(double[] pay)
{
pay = payRate;
}
// setWages method
public void setWage(int[] time, int[] pay)
{
for (int index = 0; index < NUM_EMPLOYEES; index++)
wages[index] = time[index] * pay[index];
}
//getEmployeeID method
public int getEmployeeID(int index)
{
return employee;
}
// getWage method
public double getWage(int index)
{
return wage;
}
}
The program is supposed to display each employee number and ask the user to enter that employee's hours and pay rate. It should then display each employee's identification number and gross wages. When I run the program, it simply lists everything as a zero value, including the employee ID numbers.
import java.util.Scanner;
public class moduleArrayDemo2
{
public static void main(String[] args)
{
final int NUM_EMPLOYEES = 7;
int[] time = new int[NUM_EMPLOYEES];
double[] pay = new double[NUM_EMPLOYEES];
// Create new Scanner object
Scanner keyboard = new Scanner(System.in);
// Create employee object
moduleArray2[] employee = new moduleArray2[NUM_EMPLOYEES];
// A loop that creates objects for each element
for (int i = 0; i < employee.length; i++)
employee[i] = new moduleArray2();
for (int i = 0; i < employee.length; i++)
{
System.out.print("Enter hours for Employee #" + employee[i].getEmployeeID(i) +
": ");
time[i] = keyboard.nextInt();
employee[i].setHours(time);
System.out.print("Enter how much Employee #" + employee[i].getEmployeeID(i) +
" makes per hour: ");
pay[i] = keyboard.nextDouble();
employee[i].setPayRate(pay);
}
for (int i = 0; i < employee.length; i++)
{
System.out.println("Employee #" + employee[i].getEmployeeID(i) +
" Wages: " + employee[i].getWage(i));
}
}
}
I can do arrays in a simple program, and I can do classes with programs that create instances of those classes. Arrays in a class...I feel totally lost. How do I reference the arrays in the class to get values in the program itself? Any feedback or suggestions would be greatly appreciated!
First of all you're messing up accessor methods arguments, their actual values and accessed objects.
class ModuleArray2
int[] employeeID = {5658845, 4520125, 7895122, 8777541, 8451277, 1302850, 7580489};
int NUM_EMPLOYEES = employeeID.length; // I assume you've got it defined somewhere
int[] hours = new int[NUM_EMPLOYEES];
double[] payRate = new double[NUM_EMPLOYEES];
double[] wages = new double[NUM_EMPLOYEES];
// setHours method - will reassign the whole array of `hours` with the provided argument `time` ; I'm leaving this method with a signature that you have provided just to have a place to put my comment on it
public void setHours(int[] time) {
hours = time;
// time = hours; // this is wrong - it would assign class field value to the temporary argument variable `time`, and then just throw it away (since `time` in this scope is temporary)
}
// setHours method - will set working hours in one of an array `hours` elements specified by the provided index - number of an employee it refers to
public void setHours(int employeeNumber, int workedHours) {
hours[employeeNumber] = workedHours;
}
// setPayRate method - same as above
public void setPayRate(int employeeNumber, double payRate) {
payRates[employeeNumber] = payRate;
}
// setWage method - same as above
public void setWage(int employeeNumber, double wage) {
wages[employeeNumber] = wage;
}
// getWage method - will return the wage for employee given by an index in array number
public double getWage(int employeeNumber) {
return wages[employeeNumber];
}
//getEmployeeID method - will return an ID of employee given by an index in array number
public int getEmployeeID(int employeeNumber) {
return employeeID[employeeNumber];
}
//getEmployeeIndexFromID method - will return the index of employee given by his ID number - this is inverse function of the function 'getEmployeeID'
public int getEmployeeIndexFromID(int employeeID) {
int index;
// search implementation goes here
// you should try to write it on your own
return index;
}
}
based on the Tax program change the total variable to an array that accepts 5 double values from the user then pass it to the tax method to get the tax on the total.
I made a class with an ArrayList that holds "Student" Objects and I have a toString method that prints the Students test scores,name,etc. But I keep getting "java.lang.IndexOutOfBoundsException: Index: 0, Size: 0" here is my code, if you need to see any more code just comment
public class School2 {
ArrayList <Student2> studentArray;// array of Student's
/**
* Constructor for School, creates an array of for ten Student's.
*/
public School2() {
final int NUMSTUDENTS = 10;
studentArray = new ArrayList <Student2> (NUMSTUDENTS);
}// end constructor
/**
* Method adds a student 'newStudent' to the array of Student's.
* #param newStudent - Student to be added
*/
public void add(Student2 newStudent) {
studentArray.add(newStudent);
}// end method
/**
* Method adds a Student whose name and test scores are passed in parameter.
* #param name - name of newly added Student
* #param tests - array of test scores belonging to newly added Student
*/
public void add(String name, ArrayList <Integer> testScores) {
Student2 studentAdded = new Student2(name, testScores);
studentArray.add(studentAdded);
}// end method
/**
* Method adds a Student whose name is passed in parameter.
* #param name - name of newly added Student
*/
public void add(String name) {
Student2 studentAdded = new Student2(name);
studentArray.add(studentAdded);
}// end method
/**
* Method adds a Student whose name is an empty String and test scores are 0.
*/
public void add() {
Student2 studentAdded = new Student2();
studentArray.add(studentAdded);
}// end method
/**
* Method removes all Student object 's' from array of Student's
* #param s - Student to be removed from array of Student's
*/
public void remove(Student2 s) {
for (int i = 0; i < studentArray.size(); i++) {
if (studentArray.get(i) == s) {
studentArray.remove(i);
}// end if statement
}// end for loop
}// end method
/**
* Method removes the Student whose index is passed in the parameter
* #param index - index at which the Student is located
*/
public void remove(int index) {
studentArray.remove(index);
}// end method
/**
* Method removes the Student whose name is passed in the parameter
* #param name - name of Student to be removed
*/
public void remove(String name) {
for (int i = 0; i < studentArray.size(); i++) {
if (studentArray.get(i).getName() == name) {
studentArray.remove(i);
}// end if statement
}// end for loop
}// end method
/**
* Method replaces the Student whose index is passed in the parameter with a
* different Student object 'newStudent'
* #param index - index of Student to be replaced
* #param newStudent - Student object to replace other Student
*/
public void replace(int index, Student2 newStudent) {
studentArray.set(index, newStudent);
}// end method
/**
* Method returns the student with the highest test score
* #return - Student with the highest test score
*/
public Student2 getHighScore() {
int index = 0;
int highScore = 0;
for (int i = 0; i < studentArray.size(); i++) {
if (studentArray.get(i).getHighScore() > highScore) {
index = i;
highScore = studentArray.get(i).getHighScore();
}// end if statement
}// end for loop
return studentArray.get(index);
}// end method
/**
* Method returns the class average
*
* #return - class average of test scores
*/
public int getClassAverage() {
int totalScores = 0;
int numTests = 0;
for (int i = 0; i < studentArray.size(); i++) {
for (int x = 1; x <= 3; x++) {
totalScores += studentArray.get(i).getScore(x);
}
numTests += 3;
}// end for loop
return (totalScores / numTests);
}// end method
/**
* Getter method returns a Student whose index is passed in the parameter
* #param index - index of Student object
* #return - Student object
*/
public Student2 getStudent(int index) {
return (studentArray.get(index));
}// end method
/**
* Getter method returns a Student whose name is passed in the parameter
* #param name - name of Student
* #return - Student object
*/
public Student2 getStudent(String name) {
int index = 0;
for (int i = 0; i < studentArray.size(); i++) {
if (studentArray.get(i).getName() == name) {
index = i;
}// end if statement
}// end for loop
return (studentArray.get(index));
}// end method
/**
* Method returns a string containing the names and test scores of all
* students, the class average, and the highest score and the name of the
* student with the highest score.
*/
public String toString() {
String school = "";
for (int i = 0; i < studentArray.size(); i++) {
school += "Name: " + studentArray.get(i).getName() + ":";
//nested for loop gets all 3 tests and concatenates the scores to 'school' string
for (int test = 1; test <= 3; test++) {
school += " test " + test + ": ";
school += studentArray.get(i).getScore(test);
}// end nested for loop
school += " Average: " + studentArray.get(i).getAverage();
school += " High Score: " + studentArray.get(i).getHighScore()
+ "\n";
}// end nested for loop
school += "Class Average: " + getClassAverage() + "\n";
school += "Highest score\n";
school += getHighScore() + "\n";
return school;
}// end method
}//end class
public class Student2
{
String studentName;// name of Student
ArrayList <Integer> studentScores;// test scores of student
final int NUMTESTS = 3;//Student has 3 different test scores
/**
* Constructor for Student2 class, sets name of student to an empty String
* and test scores to 0.
*/
public Student2(){
studentName = "";
studentScores = new ArrayList <Integer> (NUMTESTS);
}//end constructor
/**
* Constructor for Student2 class, sets name to String passed in parameter
* and test scores to 0.
* #param name - name of student
*/
public Student2(String name){
studentName = name;
studentScores = new ArrayList <Integer> (NUMTESTS);
}//end constructor
/**
* Constructor for Student2 class, sets name and test scores to the String
* and array passed in the parameter
*/
public Student2(String name, ArrayList<Integer> testScores){
studentName = name;
studentScores = testScores;
}//end constructor
/**
* Constructor for Student2 class, sets the name and test scores to Student2 's'.
* #param s - Student object
*/
public Student2(Student2 s){
studentName = s.getName();
studentScores = new ArrayList <Integer> (NUMTESTS);
for(int i = 0; i < studentScores.size(); i++){
studentScores.add(s.getScore(i + 1));
}//end for loop
}//end constructor
/**
* Sets name of Student to String passed in parameter
* #param name - name of Student
*/
public void setName(String name) {
studentName = name;
}// end method
/**
* Getter method for Student's name
* #return studentName - name of Student
*/
public String getName() {
return studentName;
}// end method
/**
* Setter method which re-intializes a Student's test score at a given index
* whose values are passed in the parameter
* #param whichTest - test to be set
* #param testScore - value of test to be set
*/
public void setScore(int whichTest, int testScore) {
if (whichTest >= 3) {
studentScores.set(2, testScore);
} else {
studentScores.set((whichTest - 1), testScore);
}
}// end method
/**
* Setter method, re-intializes all test scores to the array passed in the
* parameter
* #param testScores - array of test scores
*/
public void setScore(int[] testScores) {
for(int i = 0; i < testScores.length; i++){
studentScores.set(i, testScores[i]);
}//end for loop
}// end method
/**
* Getter method to get a Student's test score
* #param whichTest - test number
* #return score - score of the particular test number
*/
public int getScore(int whichTest) {
int score = 0;
if (whichTest >= 3) {
score = studentScores.get(2);
} else {
score = studentScores.get((whichTest - 1));
}
return score;
}// end method
/**
* Method calculates the average of the Student's test scores
* #return - average of Student's test scores
*/
public int getAverage() {
int total = 0;
int numTests = 0;
for (int i = 0; i < studentScores.size(); i++) {
total += studentScores.get(i);
numTests++;
}
return (total / numTests);
}// end method
/**
* Method to get the Student's highest test score
* #return highScore - Student's highest test score
*/
public int getHighScore() {
int highScore = 0;
for (int i = 0; i < studentScores.size(); i++) {
if (studentScores.get(i) > highScore) {
highScore = studentScores.get(i);
}//end if statement
}//end for loop
return highScore;
}// end method
/**
* Method returns a String containing the Student's name, test scores,
* average score and high score.
*/
public String toString() {
String student = "Name: " + getName() + ":";
for(int test = 1; test <= studentScores.size(); test++){
student += " test " + test + ": " + getScore(test);
}
student += " Average: " + getAverage();
student += " High Score: " + getHighScore();
return student;
}// end method
}//end class
Driver Code:
School2 mySchool = new School2();
ArrayList<Student2> studentArr = mySchool.studentArray;
Student2 s = new Student2("Olive Oyl", randomScores());
mySchool.add(s);
mySchool.add("Popeye", randomScores());
mySchool.add("Bluto");
mySchool.add();
System.out.println(mySchool);
Exception message:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at Student2.getScore(Student2.java:107)
at School2.toString(School2.java:176)
at java.lang.String.valueOf(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at Driver.main(Driver.java:25)`
for (int test = 1; test <= 3; test++)
Should this be
for (int test = 0; test < 3; test++)
Probably you have an error not at this loop, but in Student class.
First try this code
String school = "";
for (int i = 0; i < studentArray.size(); i++) {
school += "Name: " + studentArray.get(i).getName() + ":\n";
}
return school;
Then try change your inner loop to
for (int test = 1; test <= 3; test++) {
school += " test " + test + ": ";
school += studentArray.get(i-1).getScore(test);
}// end nested for loop
Because most likely error is here
Added.
Error is here
public Student2(){
studentName = "";
studentScores = new ArrayList <Integer> (NUMTESTS);
}
because
studentScores = new ArrayList <Integer> (NUMTESTS);
NOT fill studentScores with 4 empty integer.
After this line studentScores.size() return 0 insted of 4
There are some mistakes in your code.
Please update your code of getClassAverage() method from School2 class to
public int getClassAverage() {
int totalScores = 0;
int numTests = 0;
for (int i = 0; i < studentArray.size(); i++) {
for (int x = 1; x <= studentArray.get(i).studentScores.size(); x++) {
totalScores += studentArray.get(i).getScore(x);
}
numTests += 3;
}// end for loop
return (totalScores / numTests);
}// end method
And also toString() method of School2 class to
public String toString() {
String school = "";
for (int i = 0; i < studentArray.size(); i++) {
school += "Name: " + studentArray.get(i).getName() + ":";
//nested for loop gets all 3 tests and concatenates the scores to 'school' string
for (int test = 1; test <= studentArray.get(i).studentScores.size(); test++) {
school += " test " + test + ": ";
school += studentArray.get(i).getScore(test);
}// end nested for loop
school += " Average: " + studentArray.get(i).getAverage();
school += " High Score: " + studentArray.get(i).getHighScore()
+ "\n";
}// end nested for loop
school += "Class Average: " + getClassAverage() + "\n";
school += "Highest score\n";
school += getHighScore() + "\n";
return school;
}// end method
Also make changes in getAverage() method of Student2 class as below:
public int getAverage() {
int total = 0;
int numTests = 0;
for (int i = 0; i < studentScores.size(); i++) {
total += studentScores.get(i);
numTests++;
}
if (numTests == 0) {
return 0;
} else {
return (total / numTests);
}
}// end method
I hope you will get the point from where actually the exception is throwing, cheers.
Alright, so I'm trying to create a "sales tax program' where the user can input the items and it adds it to an array, called "costArray". I only know how to do it, almost, with a String (since I need costArray.length for the loop) but I'm kind of lost. Can anyone help point me in the right direction so I can: Take an array of numbers (doubles) and apply a multiplier to it (0.08 for sales tax percentage) and output a total number (double)? Here is what I have so far, can you tell me if I'm close? Thanks!:
public class Input
{
private Scanner keybd;
private String item;
private double cost;
private String[] costArray;
private String[] itemArray;
/**
* Constructor for objects of class Scanner
*/
public Input(int anyAmountofItems)
{
keybd = new Scanner(System.in);
costArray = new String[anyAmountofItems];
itemArray = new String[anyAmountofItems];
}
/**
* Mutator method to set the item names and costs
*/
public void setArray(){
for(int index=0; index < itemArray.length; index++){
System.out.println("Enter the item name: ");
itemArray[index] = keybd.next();}
for(int indexa=0; indexa < itemArray.length; indexa++){
System.out.println(itemArray[indexa]);
}
for(int indexb=0; indexb < costArray.length; indexb++){
System.out.println("Enter the item cost: ");
costArray[indexb] = keybd.next();}
for(int indexc=0; indexc < costArray.length; indexc++){
System.out.println(costArray[indexc]);
}
}
/**
* Accessor method to return the items cost with tax
*/
public double getTax(){
return costArray.length;
}
// /**
// * Mutator method to calculate tax on each item
// */
// public void calculateTax(){
// for(int index=0; index < costArray.length; index++){
// System.out.println(0.08 * costArray[index]);
// }
// }
}
The number ist stored in a String and you have to "convert" it to a real number (a double value)
The way to do it is shown here:
String s = "-1.234";
double value = Double.parseDouble(s);
In Java 8:
import java.util.stream.DoubleStream;
double taxCoef = 0.08;
double[] prices = {10,20,30};
double total = DoubleStream.of(prices).map(p->p*(1+taxCoef)).sum();
System.out.println(total);
output: 64.80000000000001
(alternatively, can sum up first and then multiply)
Arrays are a bad idea, if you don't know before which size they will have. Why not use an ArrayList? If you don't know it right know: You'll really will need it often!
Names of indexes inside a loop are well with 'i', 'n', 'p, q, r' or 'x', and they only exist in their own loop, so you can define a new 'i' in the second loop - no need for indexa, indexb, ... .
For learning, a double might be sufficient, but in real world, you shouldn't use double for Money amounts, but BigDecimal. The bit-representation of fractions leads else to surprising effects.
And Scanner has already methods like scanner.nextDouble () to read a Number.