如何使用Stream统计嵌套HashMap中studentSubmissions的总数量?
用Java Stream统计嵌套Map中特定类型提交的总数量
首先先把你的现有代码贴出来方便参考:
Map<String, HashMap<String, List<Submission>>> assignmentMap = new HashMap(); Map<String, List<Submission>> submissionMap = new HashMap(); List<Submission> ls = new ArrayList(); ls.add(new Submission("student1")); ls.add(new Submission("student2")); submissionMap.put("studentSubmissions", ls); assignmentMap.put("assignmentid1", submissionMap);
要统计所有studentSubmissions的总数量,同时忽略其他类型的提交(比如instructorSubmissions),我们可以利用Java Stream的链式操作优雅实现,下面给你两种常用的方案:
方案一:直接统计列表长度(高效简洁)
这种方法直接针对目标列表的长度进行累加,适合只需要总数的场景:
import java.util.Objects; // 统计总学生提交数 long totalStudentSubmissions = assignmentMap.values().stream() // 取出每个作业对应的提交Map .map(submissionMap -> submissionMap.get("studentSubmissions")) // 过滤掉没有学生提交列表的情况(避免空指针异常) .filter(Objects::nonNull) // 将列表转换为对应的元素数量 .mapToLong(List::size) // 累加所有数量 .sum(); System.out.println("总学生提交数: " + totalStudentSubmissions); // 输出2
步骤解释:
assignmentMap.values().stream():获取外层Map中所有的提交Map,转换成Stream流map(submissionMap -> submissionMap.get("studentSubmissions")):从每个提交Map中取出studentSubmissions对应的列表filter(Objects::nonNull):过滤掉那些不存在学生提交列表的条目(防止后续调用size()时抛出空指针)mapToLong(List::size):把每个列表转换成它的元素个数(用long类型避免大数量时的int溢出)sum():将所有列表的元素数累加得到总数
方案二:展开元素统计(灵活扩展)
如果后续需要对单个Submission做额外筛选(比如统计某个特定学生的提交数),可以用这种展开元素的方式:
long totalStudentSubmissions = assignmentMap.values().stream() // 把所有提交Map的键值对展开成一个流 .flatMap(submissionMap -> submissionMap.entrySet().stream()) // 只保留key为studentSubmissions的条目 .filter(entry -> "studentSubmissions".equals(entry.getKey())) // 把每个列表的元素展开成流,每个元素对应一个1 .flatMapToInt(entry -> entry.getValue().stream().mapToInt(s -> 1)) // 累加得到总数 .sum();
注意事项:
- 一定要处理
null情况:有些提交Map可能没有studentSubmissions这个key,直接调用size()会抛出NullPointerException,所以必须加过滤 - 优先用
long类型存储总数:如果提交数量很大,int可能会溢出,long更安全
内容的提问来源于stack exchange,提问作者Harshana
相关产品推荐
相关产品推荐

