Access elements of arraylist of arraylist of arraylist?

104 Views Asked by At

I am new to Java, and I am currently using BlueJ for a project. I am having troubles accessing the objects inside an ArrayList of an ArrayList of such objects. Say I have a Student object:

public class Student
{
 private String homeAddress;
 private String monthBorn;
 private String yearBorn;
 private int;

 public Student(String homeAddress, String monthBorn, String yearBorn,  
 int finalGrade)
 {
   this.homeAddress = homeAddress;
   this.monthBorn = monthBorn;
   this.yearBorn = yearBorn;
   this.finalGrade = finalGrade;
  }
}

And then methods to get address, month, year and grade. Then I have a class Class, which is an ArralyList of Student objects:

    public class Classroom
    {
      private String classroom;
      private ArrayList<Student> listOfStudents;

     public Classroom (String classroom)
     {
      this.classroom = classroom;
      listOfStudents = new ArrayList<Student>();
     }
   }

And this class includes methods to add Student objects, to list all the students in the class (listAllStudentsInClassroom) which returns an ArrayList of Student, to find the Student with the highest grade in the class (getHighestGradeStudent), and to a list of students with grades higher than a certain amount. Finally, the class School, which is an ArrayList of Classroom:

public class School
{
 private ArrayList<Classroom> school;

 public School()
 {
  school = new ArrayList<Classroom>();
  }
}

This includes methods to add a class object, and it should include methods to return the Student with the highest grade ever and a list of students from all classes with grades higher than a certain one. However, I can only get the methods to iterate through only the first class added! Here is the code for getHighestGradeStudentEver so far:

    public Student getHighestGradeStudentEver ()
    {
      Student s = school.get(0).getHighestGradeStudent();
      int highestGrade =   school.get(0).listAllStudentsInClassroom().get(0).getFinalGrade();
      for(int i =1; i< school.size(); i++){
        int highestGrade = school.get(i).listAllStudentsInClassroom().get(i).getFinalGrade();
       if(value > (highestValue)){
           highestValue = value;
           s = school.get(i).getHighestGradeStudent();
           }
         }
      return s;
     }

This only returns the student with the highest grade from the first classroom object added to School. What am I doing wrong? Sorry for the long question, I tried to be as clear as possible!

2

There are 2 best solutions below

0
On BEST ANSWER

If you can already get the highest graded student in a class, you can get that for all the classes, and find the highest grade out of all of those.

// find the highest grade in each class
ArrayList<Student> highestInEachClass = new ArrayList<>();
for (Classroom classroom : school) {
    highestInEachClass.add(classroom.getHighestGradeStudent());
}

// find the highest grade overall
Student highestGradeStudent = highestInEachClass.get(0);
for (Student student : highestInEachClass) {
    if (highestGradeStudent.getFinalGrade() < student.getFinalGrade()) {
        highestGradeStudent = student;
    }
}
return highestGradeStudent;

Alternatively, use Stream:

return school.stream().flatMap(x -> x.getListOfStudents().stream())
                      .sorted(Comparator.comparing(Student::getFinalGrade).reversed())
                      .findFirst().orElse(null);
0
On

As I understand your question, you already have a function Classroom.getHighestGradeStudent() which gives you the best student of that class. You also have a way to get the grade of a given student, since the Student object contains .finalGrade.

You want to loop through all classrooms in the school, and find the student with the highest grade.

So you have your for loop, which iterates over the classrooms. And for every classroom, you get some arbitrary student's final grade:

int highestGrade = school.get(i).listAllStudentsInClassroom().get(i).getFinalGrade();
                                                                  ^

This is likely not what you want. Instead, you want the best student's grade from that classroom. For that, you should instead use

int highestGrade = school.get(i).getHighestGradeStudent().getFinalGrade();

(If my assumption is wrong and you do not have a function getHighestGradeStudent() of a given classroom, you would need to loop over the result of listAllStudentsInClassroom() (or store that list sorted))

Then, you can continue with your code as you're doing, by updating the stored best student s if the best student of the current classroom is better than what you previously had in s.
But make sure you use either highestGrade or highestValue, not both of them. As your code stands, I don't see highestValue defined anywhere.


Note, that it's possible to make this code more efficient, if you only search for the best student in a given class once. I would do

Student bestOfClassroom = school.get(i).getHighestGradeStudent();
int highestGrade = bestOfClassroom.getFinalGrade();

so you already have your student to store in s by simply doing s = bestOfClassroom instead of searching through the whole list again.
But this is an optimization that should not be relevant for the Correctness of your program.