Stream 数据统计实战:求和、平均值、分组汇总(AI 辅助学习 Java 8)

前三篇学了 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。


系列文章导航

相关推荐
Dontla19 小时前
Hero Section(首屏大图区 / 英雄区)介绍(Web网页落地页Landing Page最顶部的区域)
前端
大模型丫丫19 小时前
Skill-Agent 如何实践:从概念到落地的完整指南
java·大数据·人工智能
NWU_LK19 小时前
【WebFlux】第四篇 —— 响应式异常处理与测试
java
fengxinzi_zack19 小时前
TagManagePage:CRUD 标签管理 + 编辑模式
后端
问商十三载19 小时前
2026大模型GEO优化体系:3层链路提收录,零成本提34%引用率附工具包
大数据·前端·人工智能
良木生香19 小时前
【C++初阶】STL—— Stack & Queue 从入门到精通:容器适配器、迭代器与经典面试题
java·开发语言·c++·算法·zookeeper
IT_陈寒19 小时前
Redis过期key的坑,差点让线上服务崩了
前端·人工智能·后端
恋猫de小郭19 小时前
AI 又又造词,Graph 就又要替代 Loop 了?
前端·人工智能·ai编程
Dontla19 小时前
Canonical URL介绍(规范网址 / 规范链接)(Canonical Tag 规范标签)HTML标签、SEO优化
前端·html·seo