Home > front end >  How to iterate over a wrapped HashMap
How to iterate over a wrapped HashMap

Time:12-08

I have a wrapped in class Marks HashMap which is subjectMark

public class Marks{
    private final Map<String, Integer> subjectMark = new HashMap<>();
}

and I want somehow to add new maps and iterate over this HashMap in my general class RecordBook.

public class RecordBook {

    private final Map<Integer, Marks> semesterSubjectMark = new HashMap<>();

    public void addSemester(int semester, String subject, int mark){
        //how to add such map - Map<semester, Map<subject, mark>>
        //semesterSubjectMark.put(semester, Map<subject, mark>)
    }
    
    public void gpa(){
        for(var semester : semesterSubjectMark.entrySet()){
            //for(var subject : (inner map which wrapped in class Marks).entrySet()){
                // ...
            // }
        }
    } 
}

I think that I should implement methods to add new maps like

public void addSubjectMark(String subject, int mark){
    subjectMark.put(subject, mark);
}

in Marks. But how to iterate over all these maps?

I tried to iterate over with for-each, but it doesn't work for inner Map.

CodePudding user response:

public class Marks {
    private final Map<String, Integer> subjectMark = new HashMap<>();

    public void addSubjectMark(String subject, int mark) {
        subjectMark.put(subject, mark);
    }

    public Map<String, Integer> getSubjectMark() {
        return subjectMark;
    }
}

Above is Marks;

public class RecordBook {

    private final Map<Integer, Marks> semesterSubjectMark = new HashMap<>();

    public void addSemester(int semester, String subject, int mark) {
        Marks marks = semesterSubjectMark.get(semester);
        if (marks == null) {
            marks = new Marks();
            semesterSubjectMark.put(semester, marks);
        }
        marks.addSubjectMark(subject, mark);
    }

    public void gpa() {
        int totalMark = 0;
        int totalCredit = 0;
        for (Map.Entry<Integer, Marks> entry : semesterSubjectMark.entrySet()) {
            Marks marks = entry.getValue();
            for (Map.Entry<String, Integer> entry1 : marks.getSubjectMark().entrySet()) {
                String subject = entry1.getKey();
                int mark = entry1.getValue();
                int credit = 0;

                if (subject.equals("Math")) {
                    credit = 2;
                }
                if (subject.equals("English")) {
                    credit = 1;
                }
                // It's something like above if's, but I don't want to write them all.

                totalMark  = mark * credit;
                totalCredit  = credit;
            }
        }
        System.out.println("totalCredit:"   totalCredit);
        System.out.println("totalCredit:"   totalCredit);
        System.out.println("avg:"   totalMark / totalCredit);
    }

}

Here u go brother, not sure if method GPA() is what u want, but that's how I sees it;

CodePudding user response:

To iterate over the nested maps, you should retrieve appropriate subjectMark from the map entry:

public void gpa() {
    for (var semester : semesterSubjectMark.entrySet()) {
        // semester is Map.Entry<Integer, Marks>
        for (var subject : semester.getValue().getSubjectMark().entrySet()) {
            // subject is Map.Entry<String, Integer>
        }
    } 

To add an entry to the outer map:

public void addSemester(int semester, String subject, int mark) {
    semesterSubjectMark.computeIfAbsent(semester, (k) -> new Marks())
        .getSubjectMark().put(subject, mark);
}
  • Related