You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Streams实现各任务平均分计算及最高均分任务查询

Java Streams 实现课程任务分数统计方法

仅可修改指定两个方法的实现逻辑,其余已有代码无需改动。


待实现方法要求

  • averageScoresPerTask:接收Stream<CourseResult>类型入参,返回Map<String, Double>类型结果,存储每个任务名称对应的平均得分,方法签名固定:
public Map<String, Double> averageScoresPerTask(Stream<CourseResult> results) {}
  • easiestTask:接收Stream<CourseResult>类型入参,返回String类型结果,对应平均得分最高的任务名称,方法签名固定:
public String easiestTask(Stream<CourseResult> results) {}

已有依赖代码

CourseResult 类定义

public class CourseResult {
    private final Person person;
    private final Map<String, Integer> taskResults;

    public CourseResult(final Person person, final Map<String, Integer> taskResults) {
        this.person = person;
        this.taskResults = taskResults;
    }

    public Person getPerson() {
        return person;
    }

    public Map<String, Integer> getTaskResults() {
        return taskResults;
    }
}

测试数据生成逻辑

内置两个测试流生成方法,分别生成编程课、历史课的课程结果流,单批次生成的结果数量可通过.limit()参数调整,计算平均分时禁止硬编码除数为固定值,必须适配任意数量的输入结果:

private final String[] programTasks = {"Lab 1. Figures", "Lab 2. War and Peace", "Lab 3. File Tree"};
private final String[] practicalHistoryTasks = {"Shieldwalling", "Phalanxing", "Wedging", "Tercioing"};

private Stream<CourseResult> programmingResults(final Random random) {
    int n = random.nextInt(names.length);
    int l = random.nextInt(lastNames.length);

    return IntStream.iterate(0, i -> i + 1)
            .limit(3)
            .mapToObj(i -> new Person(
                    names[(n + i) % names.length],
                    lastNames[(l + i) % lastNames.length],
                    18 + random.nextInt(20)))
            .map(p -> new CourseResult(p, Arrays.stream(programTasks).collect(toMap(
                    task -> task,
                    task -> random.nextInt(51) + 50))));
}

private Stream<CourseResult> historyResults(final Random random) {
    int n = random.nextInt(names.length);
    int l = random.nextInt(lastNames.length);
    AtomicInteger t = new AtomicInteger(practicalHistoryTasks.length);

    return IntStream.iterate(0, i -> i + 1)
            .limit(3)
            .mapToObj(i -> new Person(
                    names[(n + i) % names.length],
                    lastNames[(l + i) % lastNames.length],
                    18 + random.nextInt(20)))
            .map(p -> new CourseResult(p,
                    IntStream.iterate(t.getAndIncrement(), i -> t.getAndIncrement())
                            .map(i -> i % practicalHistoryTasks.length)
                            .mapToObj(i -> practicalHistoryTasks[i])
                            .limit(3)
                            .collect(toMap(
                                    task -> task,
                                    task -> random.nextInt(51) + 50))));
}

实现代码

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public Map<String, Double> averageScoresPerTask(Stream<CourseResult> results) {
    // Stream为一次性资源,先收集为列表同时获取总记录数,避免流复用报错
    List<CourseResult> resultList = results.collect(Collectors.toList());
    long totalStudentCount = resultList.size();
    // 空流直接返回空Map
    if (totalStudentCount == 0) {
        return Collections.emptyMap();
    }
    // 拍平所有任务分数条目,按任务名分组累加总分后计算平均值
    return resultList.stream()
            // 调用getTaskResults().entrySet()即可访问所有任务名、对应分数的键值对
            .flatMap(courseResult -> courseResult.getTaskResults().entrySet().stream())
            .collect(Collectors.groupingBy(
                    Map.Entry::getKey,
                    Collectors.summingDouble(Map.Entry::getValue)
            ))
            .entrySet()
            .stream()
            .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    scoreEntry -> scoreEntry.getValue() / totalStudentCount
            ));
}

public String easiestTask(Stream<CourseResult> results) {
    // 复用平均分计算逻辑,直接取平均分最高的任务名
    return averageScoresPerTask(results)
            .entrySet()
            .stream()
            .max(Map.Entry.comparingByValue())
            .map(Map.Entry::getKey)
            .orElse(null);
}

实现说明

  • 不需要硬编码除数为3,总人数通过收集后的列表长度动态获取,完全适配测试数据生成方法中.limit()参数的调整
  • 聚合分数时使用summingDouble做累加,避免整数除法导致的精度丢失
  • easiestTask直接复用平均分计算逻辑,减少重复代码,后续规则调整时只需要修改一处逻辑

内容的提问来源于stack exchange,提问作者fireballun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:15:31