如何在RecordBook中操作封装于Marks类的HashMap:添加与遍历
问题解答
一、完善数据添加逻辑
首先保留你已经想到的Marks类的addSubjectMark方法,然后在RecordBook的addSemester方法中处理学期对应Marks对象的创建与更新:
1. 完善Marks类
public class Marks { private final Map<String, Integer> subjectMark = new HashMap<>(); // 添加科目分数的方法 public void addSubjectMark(String subject, int mark) { subjectMark.put(subject, mark); } }
2. 实现RecordBook的addSemester方法
用computeIfAbsent简化逻辑,当指定学期不存在对应的Marks对象时自动创建:
public class RecordBook { private final Map<Integer, Marks> semesterSubjectMark = new HashMap<>(); public void addSemester(int semester, String subject, int mark) { // 若学期不存在则创建新的Marks实例,然后添加科目分数 semesterSubjectMark.computeIfAbsent(semester, k -> new Marks()) .addSubjectMark(subject, mark); } }
二、实现嵌套Map的遍历
由于subjectMark是Marks类的私有成员,需要给Marks类添加只读的Map访问方法,既满足遍历需求又保证内部数据封装性,之后就能在gpa方法中正常遍历:
1. 给Marks类添加获取科目分数的方法
public class Marks { private final Map<String, Integer> subjectMark = new HashMap<>(); public void addSubjectMark(String subject, int mark) { subjectMark.put(subject, mark); } // 返回不可修改的Map,防止外部篡改内部数据 public Map<String, Integer> getSubjectMarks() { return Collections.unmodifiableMap(subjectMark); } }
2. 实现gpa方法的遍历逻辑
用普通for-each循环:
public void gpa() { for (var semesterEntry : semesterSubjectMark.entrySet()) { int semester = semesterEntry.getKey(); Marks marks = semesterEntry.getValue(); System.out.println("当前学期:" + semester); // 遍历当前学期的所有科目分数 for (var subjectEntry : marks.getSubjectMarks().entrySet()) { String subject = subjectEntry.getKey(); int mark = subjectEntry.getValue(); System.out.println("科目:" + subject + ",分数:" + mark); // 在这里添加GPA计算的具体逻辑 } } }
或者用Stream API简化写法:
public void gpa() { semesterSubjectMark.forEach((semester, marks) -> { System.out.println("当前学期:" + semester); marks.getSubjectMarks().forEach((subject, mark) -> { System.out.println("科目:" + subject + ",分数:" + mark); // GPA计算逻辑 }); }); }
核心要点总结
- 通过
computeIfAbsent简化学期对应Marks对象的创建与更新逻辑 - 给
Marks类添加只读的Map访问方法,平衡外部访问需求和内部数据封装性 - 遍历嵌套结构时,先获取外层Map的
Marks对象,再通过其暴露的方法获取内部科目分数Map进行遍历
内容的提问来源于stack exchange,提问作者Kenion
相关产品推荐
相关产品推荐

