0

My code is supposed to print out the student with the highest range. There is a method in my Student class which calculates the range, while in my Classroom class there is another method that determines which student had the highest growth. My problem comes in the class Student, I get an Out of Bounds Exception in the addExamScore method.

Main class:

public class ClassroomTester 
{
    public static void main (String[] args)
    {
        Classroom c = new Classroom(2);
        
        Student ada = new Student("Ada", "Lovelace", 12);
        ada.addExamScore(44);
        ada.addExamScore(65);
        ada.addExamScore(77);

        Student alan = new Student("Alan", "Turing", 11);
        alan.addExamScore(38);
        alan.addExamScore(24);
        alan.addExamScore(31);

        c.addStudent(ada);
        c.addStudent(alan);
        c.printStudents();
        
        Student mostImproved = c.getMostImprovedStudent();
        System.out.println("The most improved student is " + mostImproved.getName());
    }
}

Student class:

public class Student
{
    private static final int NUM_EXAMS = 4;
    
    private String firstName;
    private String lastName;
    private int gradeLevel;
    private double gpa;
    
    private int[] exams;
    private int numExamsTaken;

    public Student(String fName, String lName, int grade)
    {
        firstName = fName;
        lastName = lName;
        gradeLevel = grade;
        exams = new int[numExamsTaken];
        numExamsTaken = 0;
    }
    
    public int getExamRange()
    {
    int maximum = 0;
    int minimum = 0;
    for(int i = 0; i < exams.length; i++){
        if(exams[i]<exams[minimum]){
        minimum = i;    
        }
        else if(exams[i]>exams[maximum]){
        maximum = i;    
        }
            
    }
    return exams[maximum]-exams[minimum];
    }
    
    public String getName()
    {
        return firstName + " " + lastName;
    }
    
    public void addExamScore(int score)
    {
        exams[numExamsTaken] = score;
        numExamsTaken++;
    }
    
    public void setGPA(double theGPA)
    {
        gpa = theGPA;
    }
    
    public String toString()
    {
        return firstName + " " + lastName + " is in grade: " + gradeLevel;
    }
}
Zack C.
  • 35
  • 3
  • Array of what size you expect to be created at `exams = new int[numExamsTaken];`? What makes you think so? – Pshemo Jul 22 '20 at 17:31
  • You cannot grow an array by adding an element to the next index. You should change to use a List. – jnorman Jul 22 '20 at 17:33
  • 1
    Yes, as the other comments already mentioned – in Java, an array has a *fixed size*, it cannot grow. To allow to add more elements, array contents must be copied to a new array with a greater size. An `ArrayList` wraps an array and automatically grows when more capacity is needed. – MC Emperor Jul 22 '20 at 17:39

3 Answers3

0

First, you're initializing exams in the constructor the line before you initialize numExamsTaken, the order should be reversed because you need to know what numExamsTaken is before using it. I'd recommend storing the maximum and minimum as scores instead of indexes but that's just personal preference I think it makes the code more readable, so up to you. The index out of bounds problem probably has to do with your addExamScore method. If you've taken 4 exams it might look like [90, 85, 74, 82] where the indexes are 0, 1, 2, 3 and numExamsTaken = 4. Indexes starting at 0 is called zero-indexing and is used in most if not all programming languages.

exams[3] = 82 and exams[4] is going to give you an out of bounds error. Since you're not using an arrayList every time you want to add an element you're going to need to create an empty array of one size bigger than your current array, copy the previous scores over, and slide the new score into the last slot (in the case above would be index 4, which isn't out of bounds in the new array). Store your new array where your old array was in exams[].

Brendan
  • 1
  • 1
0

Index out of bounds exception shows when array crosses it limits to store the value.

You have declared array of size '0' inside the constructor in the line exams = new int[numExamsTaken]; initialize the size of the array with your expected range or use ArrayList to add values without specifying the size in prior

Rashedul.Rubel
  • 3,446
  • 25
  • 36
0

The problem with your code here is that you are trying to access a value in an array, which has not been allocated there. This is why the output is giving a ArrayIndexOutOfBoundsException, since you are trying to access an index in an array that is out of bounds of the array. In Java, arrays are fixed in size, meaning once you call new on an array, you cannot change the size of it without calling new on another array with a different size. In this case, it will be easiest to use a List, like an ArrayList, which does all of the resizing, copying, etc. for you, so you can use it as if it were a dynamically sized array. Your code would change to look something like this:

public class Student
{
    // ...
    private List<Integer> exams;
    // ...

    public Student(String fName, String lName, int grade)
    {
        // ...
        exams = new ArrayList<>();
        // ...
    }
    
    public int getExamRange()
    {
        int maximum = 0;
        int minimum = 100;
        for(int i = 0; i < exams.length; i++){
            if (exams.get(i) > maximum) {
                maximum = exams.get(i);
            }
            if (exams.get(i) < minimum) {
                minimum = exams.get(i);
            }
        }

        return maximum - minimum;
    }

    public void addExamScore(int score)
    {
        exams.add(score);
        numExamsTaken++;
    }
}

You can look more into List and ArrayList documentation at the java API website. Also, your logic for getting the minimum element is not correct, since if you have no scores that are less than 0, it will always assume that the minimum score is 0. You can fix this by setting the initial value to 100(the maximum possible value of a test score), or using another method that you prefer.