导航
电话
咨询
地图
顶部
在日常数据处理中,我们经常会遇到需要统计列表中特定类别元素出现频率的场景。例如,在一个包含家庭成员信息的列表中,我们可能需要统计不同类型的家庭成员(如兄弟姐妹、子女、配偶)各自有多少人。原始数据可能以 list> 的形式存在,其中每个 map 代表一个成员的详细信息,例如:
| Add_Family_Member | Full_Name | Date_Of_Birth | Gender | | Sibling | Sibling name | 12-12-1990 | Male | | Sibling | Sibling name2 | 12-12-1990 | Male | | Sibling | Sibling name2 | 12-12-1990 | Male | | Child | Child name | 12-12-2010 | Male | | Child | Child name2 | 12-12-2000 | Female | | Spouse | Spouse name | 12-12-1990 | Male |
我们的目标是高效地统计出 "Sibling" 有 3 个,"Child" 有 2 个,"Spouse" 有 1 个。
虽然 List> 可以存储这类数据,但它在处理时存在一些局限性,例如缺乏类型安全,在访问数据时需要通过字符串键来获取,容易出错且代码可读性差。对于结构化的数据,更推荐的做法是定义一个POJO(Plain Old Java Object)类来封装数据。这不仅提供了编译时类型检查,还能使代码更清晰、更易于维护。
以下是 FamilyMember POJO 类的定义:
import java.time.LocalDate; // Java 8日期API public class FamilyMember { private String memberType; private String fullName; private LocalDate dateOfBirth; private String gender; public FamilyMember(String memberType, String fullName, LocalDate dateOfBirth, String gender) { this.memberType = memberType; this.fullName = fullName; this.dateOfBirth = dateOfBirth; this.gender = gender; } // Getters public String getMemberType() { return memberType; } public String getFullName() { return fullName; } public LocalDate getDateOfBirth() { return dateOfBirth; } public String getGender() { return gender; } // Setters (可选,根据业务需求添加) public void setMemberType(String memberType) { this.memberType = memberType; } public void setFullName(String fullName) { this.fullName = fullName; } public void setDateOfBirth(LocalDate dateOfBirth) { this.dateOfBirth = dateOfBirth; } public void setGender(String gender) { this.gender = gender; } }
Java 8 引入的 Stream API 提供了强大且富有表现力的数据处理能力。结合 Collectors.groupingBy() 和 Collectors.counting(),我们可以非常简洁地实现按类型计数的需求。
下面是具体的实现代码,展示了如何使用 FamilyMember POJO 和 Stream API 进行统计:
import java.time.LocalDate; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class FamilyMemberCounter { public static void main(String[] args) { // 1. 创建FamilyMember对象列表作为示例数据 List listOfFamilyMember = Arrays.asList( new FamilyMember("Sibling", "Sibling name", LocalDate.of(1990, 12, 12), "Male"), new FamilyMember("Sibling", "Sibling name2", LocalDate.of(1990, 12, 12), "Male"), new FamilyMember("Sibling", "Sibling name3", LocalDate.of(1990, 12, 12), "Male"), new FamilyMember("Child", "Child name", LocalDate.of(2010, 12, 12), "Male"), new FamilyMember("Child", "Child name2", LocalDate.of(2000, 12, 12), "Female"), new FamilyMember("Spouse", "Spouse name", LocalDate.of(1990, 12, 12), "Male") ); // 2. 使用Stream API进行分组和计数 // 将列表转换为流,然后使用Collectors.groupingBy按memberType分组,并用Collectors.counting统计每个组的数量 Map countMembers = listOfFamilyMember.stream() .collect(Collectors.groupingBy(FamilyMember::getMemberType, // 分组依据:FamilyMember的memberType属性 Collectors.counting())); // 对每个分组内的元素进行计数 // 3. 打印结果 System.out.println(countMembers); } }
代码解析:
输出结果:
{Spouse=1, Sibling=3, Child=2}
这个输出清晰地展示了每种家庭成员类型的数量,与我们的预期完全一致。
// 假设 inputList 是 List> Map countMapFromRaw = inputList.stream() .collect(Collectors.groupingBy(map -> map.get("Add_Family_Member"), Collectors.counting()));
但这种方式不如使用POJO类型安全和优雅,因为字符串键容易拼写错误且编译时无法检查。
本文详细阐述了如何利用Java 8 Stream API中的 Collectors.groupingBy() 和 Collectors.counting() 功能,高效地统计集合中特定类型元素的出现次数。通过将原始的 List> 结构优化为POJO类,我们不仅提升了代码的健壮性和可读性,还展示了流式操作在数据聚合方面的强大能力。掌握这些技术,可以显著提高Java应用程序中数据处理的效率和代码质量。
# ai # 重构 # 封装 # 这是 # 处理器 # red # function # 多核 # 家庭成员 # 对象 # Java # String # 泛型 # 字符串 # 数据结构 # map # Object # 代码可读性 # 流式 # 转换为 # ide # 数据处理 # 组中 # 展示了 # 收集器 # java应用程序
相关栏目: 【 行业资讯 】 【 网络运营 】 【 GEO优化 】 【 营销推广 】 【 SEO优化 】 【 技术教程 】 【 代码知识 】 【 AI推广 】
相关推荐: Win10如何设置双wan路由器 Win10双wan路由器设置方法【指南】 LINUX怎么设置系统语言_LINUX修改中文环境 Win11怎么快速锁屏_Win11一键锁屏快捷键Win+L【基础】 Win11怎么开启专注模式_Windows11时钟应用Focus Session 如何用正则与预处理高效拦截带干扰符的恶意域名 Win10如何备份注册表_Win10注册表备份步骤【攻略】 VSC怎么快速定位PHP错误行_错误追踪设置法【方法】 Python项目维护经验_长期演进说明【指导】 LINUX下如何配置VLAN虚拟局域网_在LINUX交换机与服务器上的实现 Mac如何彻底清理浏览器缓存?(Safari与Chrome) Python异步编程高级项目教程_asyncio协程任务管理实战 Win11玩游戏全屏闪退怎么办_Win11全屏优化禁用设置【教程】 C++如何使用std::async进行异步编程?(future用法) 如何用::实现工具类方法调用_php静态工具类设计技巧【技巧】 Windows10系统怎么查看已保存密码_Win10凭据管理器查看Web Win11怎么关闭系统提示音_Windows11声音方案设为无声教程 Win11开机自检怎么关闭_跳过Win11开机磁盘扫描修复方法【技巧】 Win11怎么打开cmd_Windows 11运行命令提示符多种方法【步骤】 Mac如何修复应用程序权限问题_Mac磁盘工具修复权限【教程】 如何使用Golang优化模块引入路径_Golanggo mod tidy清理与优化方法 Win11怎么设置闹钟_Windows 11时钟应用闹钟设置指南【详解】 c# 在高并发场景下,委托和接口调用的性能对比 c++怎么操作redis数据库_c++ hiredis库连接与命令执行【实战】 Win11如何更改用户账户文件夹名称 Win11修改C:Users用户名【终极教程】 Win10如何关闭安全中心所有通知 Win10禁用Windows Defender提醒【设置】 如何使用Golang defer优化性能_减少不必要的函数调用 Win11怎么开启HDR模式_Windows 11高动态范围显示设置指南【详解】 Win10如何卸载WindowsDefender_Win10卸载Defender教程【方法】 Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康 如何在 Go 项目开发中正确处理本地包导入与远程模块路径的一致性问题 如何使用Golang实现容器自动化运维_Golang Docker运维管理方法 Win11怎么更改默认打开方式_Win11关联文件格式教程【详解】 Win10怎么安装AdobeAcrobat_Win10安装PDF编辑器教程【步骤】 Python正则表达式实战_模式匹配说明【教程】 Win11怎么设置桌面图标间距_Windows11注册表IconSpacing修改 Win11怎么查看激活状态_查询Windows 11是否已永久激活【详解】 如何在Golang中写入XML文件_生成符合规范的XML数据 Windows10系统怎么查看防火墙状态_Win10安全中心网络保护 C++中的协变与逆变是什么?C++函数指针与返回类型详解【类型系统】 Python类装饰器使用_元编程解析【教程】 php删除数据怎么软删除_添加is_del字段标记删除【技巧】 Windows的开始菜单如何自定义_开始菜单磁贴布局与应用管理【教程】 Mac如何创建和管理多个桌面空间_Mac高效多任务处理【技巧】 Win11怎么关闭任务栏小图标_Windows11任务栏角溢出设置 如何使用正则表达式精确匹配最多含一个换行符的 start-end 区段 Win11怎么关闭触摸屏_禁用Win11笔记本触摸屏功能设置【教程】 Win11如何更改鼠标滚轮速度 Win11调整滑轮滚动行数【设置】 win11 OneDrive怎么彻底关闭 Win11禁用并卸载OneDrive教程【分享】 Windows怎样关闭开始菜单推荐广告_Windows关闭开始菜单推荐设置【步骤】 如何使用Golang实现函数指针_函数变量与回调示例
赣ICP备2024031479号