Home > Mobile >  How to inject function to method in java to reduce code repetition?
How to inject function to method in java to reduce code repetition?

Time:01-07

this is my first post on stack overflow.

I'm currently learning Java and during my current project I need to print stats of students depending on the different courses: "Java", "DSA", "Databases", "Spring". I managed to get right data but as you can see below in code it is to many code repetition. Do you know mayby how to inject e.g. "getJavaPoints()" function when "Java" String is passed to printInfoAboutTopLearners(String courseName) methode?

I don't use DB as repository currently as it is just learining project the repository is ArrayList<Student>.

The goal is to simplify code below:

public static void printInfoAboutTopLearners(String courseName) {

    System.out.println(courseName);
    System.out.println("id     points  completed");

    ArrayList<Student> students = StudentRepository.getStudentRepository();

    if (courseName.equals("Java")) {
        students
                .stream()
                .sorted(Comparator.comparingInt(Student::getJavaPoints).reversed())
                .filter(student -> student.getJavaPoints() != 0)
                .forEach(student -> System.out.printf(Locale.US,
                        "%d  %-8d %.1f%%\n",
                        student.getId(),
                        student.getJavaPoints(),
                        (double) student.getJavaPoints() * 100 / JAVA_POINTS));
    }

    if (courseName.equals("DSA")) {
        students
                .stream()
                .sorted(Comparator.comparingInt(Student::getDsaPoints).reversed())
                .filter(student -> student.getDsaPoints() != 0)
                .forEach(student -> System.out.printf(Locale.US,
                        "%d  %-8d %.1f%%\n",
                        student.getId(),
                        student.getDsaPoints(),
                        (double) student.getDsaPoints() * 100 / JAVA_POINTS));
    }

    if (courseName.equals("Databases")) {
        students
                .stream()
                .sorted(Comparator.comparingInt(Student::getDbPoints).reversed())
                .filter(student -> student.getDbPoints() != 0)
                .forEach(student -> System.out.printf(Locale.US,
                        "%d  %-8d %.1f%%\n",
                        student.getId(),
                        student.getDbPoints(),
                        (double) student.getDbPoints() * 100 / JAVA_POINTS));
    }

    if (courseName.equals("Spring")) {
        students
                .stream()
                .sorted(Comparator.comparingInt(Student::getSpringPoints).reversed())
                .filter(student -> student.getSpringPoints() != 0)
                .forEach(student -> System.out.printf(Locale.US,
                        "%d  %-8d %.1f%%\n",
                        student.getId(),
                        student.getSpringPoints(),
                        (double) student.getSpringPoints() * 100 / JAVA_POINTS));
    }
}

Below Student class:

public class Student {

private final int ID_BASE = 10000;

private int id;
private String firstName;
private String lastName;
private String email;
private int javaPoints;
private int dsaPoints;
private int dbPoints;
private int springPoints;

public Student(String firstName, String lastName, String email) {
    this.id = idGenerator();
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
    this.javaPoints = 0;
    this.dsaPoints = 0;
    this.dbPoints = 0;
    this.springPoints = 0;
}

public int idGenerator(){
    return ID_BASE   StudentRepository.getSize();
} //Getters and Setters bellow

CodePudding user response:

You have a lot going on here, so without re-writing everything myself, I would suggest you embrace OOD and re-work your classes a bit. You already have a Student class. You should also had a Course class that contains a Map of students with their scores. You can then remove the various point fields from your student class. I'd also keep a CourseRepository class.

Course's have Students, Students don't have Courses.

Then your logic would go something like:

  1. Get Course from CourseRepository using the courseName
  2. Get Get the list of Students and their scores from the Course
  3. Sort the list
  4. Output the list

CodePudding user response:

Ryan, I created Course class:

public class Course {
private final int DEFAULT_SCORE = 0;
private String courseName;
private Map<Student, Integer> studentsWithScore;

public Course(String courseName) {
    this.courseName = courseName;
    this.studentsWithScore = new HashMap<>();
}

public void addNewStudentToCourse(Student student){
    this.studentsWithScore.put(student, DEFAULT_SCORE);
}

public void updateScore(Student student, int score){
    this.studentsWithScore.replace(student, score);
}

public Map<Student, Integer> getStudentsWithScore(){
    return studentsWithScore;
}

}

Is this you mean that class Course should contains a Map of students with their scores? Program has to have also functionalty to print student with all score information for all 4 courses available. If i thinking good now i just new to create method which go through all courses in CourseRepository and return array of scores for passed student?

  •  Tags:  
  • Related