Java 11基于聚合次数的Stream分组排序(仅可消费一次Stream)
解决方案:单次消费Stream生成排序后的分类列表
核心实现代码
import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; public class CategoryProcessor { public List<String> processCategoryStream(Stream<MyType> myTypeStream) { return myTypeStream // 统计每个分类的出现次数,生成<分类, 次数>的映射 .collect(Collectors.groupingBy(MyType::getCategory, Collectors.counting())) // 将映射的键值对转为流,执行排序逻辑 .entrySet() .stream() // 排序规则:先按出现次数降序,次数相同时按分类字典序升序 .sorted(Comparator.comparingLong(Map.Entry::getValue) .reversed() .thenComparing(Map.Entry::getKey)) // 提取排序后的分类字符串 .map(Map.Entry::getKey) // 收集为最终列表 .collect(Collectors.toList()); } // 示例自定义MyType类 static class MyType { private String category; public MyType(String category) { this.category = category; } public String getCategory() { return category; } } }
关键逻辑说明
- 单次消费适配:整个流程基于原Stream完成统计、排序、收集,仅消费原Stream一次,完全符合限制要求。
- 计数逻辑:通过
groupingBy配合counting下游收集器,一次性完成分类次数统计,避免额外的Stream操作。 - 排序优先级:通过
Comparator组合实现双重排序:先以次数降序为主规则,次数相同时以分类字符串的自然字典序升序为次要规则。
示例验证
若输入Stream包含以下MyType对象:
- category1(出现5次)
- categoryA(出现3次)
- categoryB(出现3次)
- categoryX(出现2次)
最终输出列表为:[category1, categoryA, categoryB, categoryX],完全匹配需求中的排序规则。
内容的提问来源于stack exchange,提问作者Sarthak Shetty
相关产品推荐
相关产品推荐

