前三篇学了 Collectors、flatMap。今天在一个完整的博客数据场景中,综合运用 Stream + Collectors 实现数据统计、分组汇总、标签云、趋势分析。
一、整体概览:一键获取所有统计信息
java
IntSummaryStatistics stats = blogs.stream()
.collect(Collectors.summarizingInt(BlogData::getViews));
stats.getCount(); // 7 篇文章
stats.getSum(); // 2180 总阅读
stats.getAverage(); // 311 平均阅读
stats.getMax(); // 500 最高阅读
stats.getMin(); // 180 最低阅读
一次遍历获取所有统计信息,比分别调用五次高效。
二、按作者分组汇总
java
Map<String, AuthorSummary> summaries = blogs.stream()
.collect(Collectors.groupingBy(
BlogData::getAuthor,
Collectors.collectingAndThen(
Collectors.toList(),
list -> new AuthorSummary(
list.size(), // 文章数
list.stream().mapToInt(BlogData::getViews).sum(), // 总阅读
list.stream().mapToInt(BlogData::getViews).average().orElse(0), // 平均阅读
list.stream().mapToInt(BlogData::getViews).max().orElse(0), // 最高阅读
list.stream().filter(BlogData::isPublished).count() // 已发布数
)
)
));
输出:
makefile
张三: 文章 3 篇 (已发布: 2), 总阅读: 730, 平均: 243, 最高: 350
李四: 文章 2 篇 (已发布: 2), 总阅读: 900, 平均: 450, 最高: 500
王五: 文章 2 篇 (已发布: 1), 总阅读: 550, 平均: 275, 最高: 300
三、标签云:flatMap + groupingBy + 排序
java
// 统计标签频率
Map<String, Long> tagFrequency = blogs.stream()
.flatMap(b -> b.getTags().stream())
.collect(Collectors.groupingBy(tag -> tag, Collectors.counting()));
// 按频率降序展示
tagFrequency.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.forEach(e -> System.out.println(" " + e.getKey() + " (" + e.getValue() + ")"));
输出:
scss
Java (4)
前端 (2)
Optional (1)
Docker (1)
Vue (1)
...
四、趋势分析:排序 + Top N
阅读量 Top 3
java
blogs.stream()
.sorted(Comparator.comparingInt(BlogData::getViews).reversed())
.limit(3)
.forEach(b -> System.out.println(" " + b.getTitle() + " (" + b.getViews() + ")"));
最低阅读量的已发布文章
java
blogs.stream()
.filter(BlogData::isPublished)
.min(Comparator.comparingInt(BlogData::getViews))
.ifPresent(b -> System.out.println(" " + b.getTitle() + " (" + b.getViews() + ")"));
五、运行结果
ini
=== 整体概览 ===
文章总数: 7
总阅读量: 2180
平均阅读: 311
最高: 500 / 最低: 180
=== 按作者汇总 ===
张三: 3 篇, 总阅读 730, 平均 243, 最高 350
李四: 2 篇, 总阅读 900, 平均 450, 最高 500
王五: 2 篇, 总阅读 550, 平均 275, 最高 300
=== 按分类统计 ===
Java: 4 篇
前端: 2 篇
运维: 1 篇
各分类平均阅读: {Java=257.5, 运维=250.0, 前端=450.0}
=== 标签云 ===
Java #### (4)
前端 ## (2)
Stream # (1)
...
=== 趋势分析 ===
阅读量 Top 3:
Vue3 API (500 阅读)
React Hooks (400 阅读)
Stream 详解 (350 阅读)
六、本周学习总结
第四周我们学习了 Collectors 进阶,完整路线:
bash
周二:Collectors 全家桶------toList/joining/groupingBy/partitioningBy/summarizing
周四:flatMap 深入------一对多场景、标签提取、反向索引
周六:数据统计实战------求和、平均值、分组汇总、标签云(本篇)
核心收获:
| 知识点 | 关键方法 | 一句话 |
|---|---|---|
| toList/toSet/toMap | 转集合 | 收集为数据结构 |
| joining | 拼接字符串 | 带分隔符、前后缀 |
| groupingBy | 分组 | 按条件分组 + 下游收集器 |
| partitioningBy | 分区 | 按 true/false 分两组 |
| summarizing | 汇总统计 | 一次获取 count/sum/avg/max/min |
| flatMap | 扁平化 | 一对多场景的利器 |
| collectingAndThen | 后处理 | 分组后自定义转换 |
七、下周预告
第五周进入 Optional,学习如何优雅地处理空值,告别 NullPointerException。
系列文章导航:
- 10-Collectors全家桶
- 11-flatMap一对多场景
- 12-Stream数据统计汇总(本篇) 更多请关注我的微信公众号,感谢!
