3

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!

Dhiral Kaniya
  • 1,941
  • 1
  • 19
  • 32
Sveva
  • 33
  • 4
  • 7
    one thing that you **must** change is that class named `Class`...rename it! Does that code even compile with variables `class`? Maybe a better name could be `Standard`, `Grade` or `Division`. – Naman Nov 11 '18 at 10:58
  • When you are writing a code please don't use Java keywords as variables names – Sandeepa Nov 11 '18 at 11:02
  • Done, sorry for the confusion. Hope it's better now. – Sveva Nov 11 '18 at 11:02
  • I know, but what can use instead of get(0)? It needs to be an int index, doesn't it? – Sveva Nov 11 '18 at 11:06
  • If you already have `getHighestGradeStudent` which returns the highest grade *per school*. Then all you need to do is compare the list of these students *across a list of school*. So, iterate over the list of school and compare their highestGradeStudent to find the one with highest amongst all ... *compare the list of these students* would require a `Comparator` based on their finalGrade to say which one is higher in grades. – Naman Nov 11 '18 at 11:08
  • You code has bracketing issues as well, please fix them so copy and pasting into an editor is easier and your intentions are clear. – shayaan Nov 11 '18 at 11:20
  • what do you exactly need? HighestGradeStudent across the all school or HightestGradeStudent for all schools? – Dhiral Kaniya Nov 11 '18 at 11:22
  • HighestGradeStudent ever recorded in the School. So the student with the highest grade across all instances Classroom. – Sveva Nov 11 '18 at 11:51
  • HighestGradeStudent returns the student object with the highest grade per Classroom. – Sveva Nov 11 '18 at 11:51
  • The title of this question scares me.. – Taslim Oseni Nov 11 '18 at 17:39

2 Answers2

2

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.

lucidbrot
  • 5,378
  • 3
  • 39
  • 68
2

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);
Sweeper
  • 213,210
  • 22
  • 193
  • 313