Java使用Stream API分组求平均值时Collection<Integer>无法转int怎么解决
问题原因
Collectors.averagingInt()要求传入的转换函数为每个CourseResult对象返回单个int值,你当前返回的是taskResults.values()对应的Collection<Integer>集合,类型不匹配因此触发编译报错。
另外要注意:如果同一个Person可能对应多个CourseResult实例,需要将所有关联的taskResults中的整数值全部合并后再计算平均值,避免分批次计算平均值再二次平均的逻辑错误。
正确实现
Java 9+ 写法(推荐)
借助Collectors.flatMapping先将所有成绩值打平,再统一计算平均值:
public Map<Person, Double> totalScores(Stream<CourseResult> programmingResults) { return programmingResults.collect(Collectors.groupingBy( CourseResult::getPerson, Collectors.flatMapping( courseResult -> courseResult.getTaskResults().values().stream(), Collectors.averagingInt(Integer::intValue) ) )); }
Java 8 兼容写法
如果使用Java 8没有内置flatMapping收集器,可以用collectingAndThen实现相同逻辑:
public Map<Person, Double> totalScores(Stream<CourseResult> programmingResults) { return programmingResults.collect(Collectors.groupingBy( CourseResult::getPerson, Collectors.collectingAndThen( Collectors.toList(), personResults -> personResults.stream() .map(CourseResult::getTaskResults) .map(Map::values) .flatMap(Collection::stream) .mapToInt(Integer::intValue) .average() // 无成绩时默认返回0.0,可根据业务需求调整默认值 .orElse(0.0) ) )); }
简化写法(仅适用于每个Person对应唯一CourseResult的场景)
如果业务逻辑保证每个Person在流中只会存在一个对应的CourseResult实例,可以直接用toMap收集,逻辑更简单:
public Map<Person, Double> totalScores(Stream<CourseResult> programmingResults) { return programmingResults.collect(Collectors.toMap( CourseResult::getPerson, courseResult -> courseResult.getTaskResults().values().stream() .mapToInt(Integer::intValue) .average() .orElse(0.0) )); }
内容的提问来源于stack exchange,提问作者Wtht.Nws
相关产品推荐
相关产品推荐

