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

Java 8 Stream统计爱好学生数及排序相关技术咨询

Java Stream 爱好统计与排序问题解析

一、先修正统计学生数量的代码

你当前的collect8代码计算的是爱好对应学生的ID总和,而不是学生数量,这和你想要的统计需求不符。正确的统计每个爱好的学生数应该这样写:

// 用counting()统计数量,返回Long类型
Map<String, Long> hobbyCountMap = data.stream()
    .flatMap(student -> student.getHobbies().stream())
    .collect(Collectors.groupingBy(
        hobby -> hobby,
        Collectors.counting()
    ));

或者用summingInt返回Integer类型:

Map<String, Integer> hobbyCountMap = data.stream()
    .flatMap(student -> student.getHobbies().stream())
    .collect(Collectors.groupingBy(
        hobby -> hobby,
        Collectors.summingInt(h -> 1)
    ));

这样得到的才是cricket=4、football=5这类符合需求的统计结果。


二、问题1:排序后结果未按值排序的原因

你用Collectors.toMap()收集排序后的元素时,默认返回的是HashMap——这是一个无序集合,它不会保留Stream排序后的顺序,所以你看到的结果始终是混乱的。

要解决这个问题,需要使用Collectors.toMap()的重载方法,指定返回LinkedHashMap——它会严格维护元素的插入顺序,这样就能保留排序后的结果了。修改后的排序代码如下:

// 按数量升序排列,如需降序可在sorted后加.reversed()
Map<String, Integer> sortedHobbyCountMap = hobbyCountMap.entrySet().stream()
    .sorted(Map.Entry.<String, Integer>comparingByValue())
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (oldValue, newValue) -> oldValue, // 处理键冲突(此处不会出现)
        LinkedHashMap::new // 指定返回有序的LinkedHashMap
    ));

这样输出的结果就会严格按照值的升序排列了。


三、问题2:能否在分组操作中直接完成排序?

严格来说,Collectors.groupingBy本身并不支持在分组过程中直接排序,因为分组的核心是按键聚合数据,排序是独立的顺序调整操作。不过我们可以把统计和排序合并成一条链式调用,不用分成两个独立的collect操作,写法如下:

// 一步完成统计+升序排序
Map<String, Integer> sortedHobbyCountMap = data.stream()
    .flatMap(student -> student.getHobbies().stream())
    .collect(Collectors.groupingBy(
        hobby -> hobby,
        Collectors.summingInt(h -> 1)
    ))
    .entrySet().stream()
    .sorted(Map.Entry.comparingByValue())
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (a, b) -> a,
        LinkedHashMap::new
    ));

这种先分组统计、再排序收集的方式效率更高,避免了先排序再分组带来的额外性能消耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:34:48