Java 8中如何按PackageType对多字段进行分组汇总?
Java 8 实现多字段分组汇总
Java 8 没有内置支持多字段同时生成LongSummaryStatistics的收集器,你可以通过自定义汇总容器和收集器来实现需求:
1. 定义自定义汇总容器类
这个类封装两个LongSummaryStatistics实例,分别对应filesCount和usedSpaceBytes的统计需求,同时实现累加、合并逻辑:
@lombok.Value @lombok.Builder private static class SummaryResult { LongSummaryStatistics filesCountStats; LongSummaryStatistics usedSpaceStats; // 累加单个RepositorySummaryValue的数据到统计容器 public static SummaryResult accumulate(SummaryResult result, RepositorySummaryValue item) { result.filesCountStats.accept(item.getFilesCount()); result.usedSpaceStats.accept(item.getUsedSpaceBytes()); return result; } // 合并两个统计容器(用于并行流场景) public static SummaryResult combine(SummaryResult left, SummaryResult right) { left.filesCountStats.combine(right.filesCountStats); left.usedSpaceStats.combine(right.usedSpaceStats); return left; } // 创建初始空的统计容器 public static SummaryResult empty() { return SummaryResult.builder() .filesCountStats(new LongSummaryStatistics()) .usedSpaceStats(new LongSummaryStatistics()) .build(); } }
2. 修改Stream收集逻辑
使用Collector.of()创建自定义收集器,配合groupingBy完成分组多字段汇总:
final Map<PackageType, SummaryResult> summaryMap = artifactory.getStorageInfo() .getRepositorySummaries() .stream() .map(RepositorySummaryValue::from) .collect(Collectors.groupingBy( RepositorySummaryValue::getPackageType, Collector.of( SummaryResult::empty, SummaryResult::accumulate, SummaryResult::combine ) ));
3. 使用汇总结果
你可以像操作普通LongSummaryStatistics一样获取每个字段的统计值(总和、最大值、最小值、平均值等):
for (Map.Entry<PackageType, SummaryResult> entry : summaryMap.entrySet()) { PackageType packageType = entry.getKey(); SummaryResult stats = entry.getValue(); System.out.println("包类型: " + packageType); // 文件数量统计 LongSummaryStatistics fileStats = stats.getFilesCountStats(); System.out.printf("文件总数: %d, 最大文件数: %d, 最小文件数: %d%n", fileStats.getSum(), fileStats.getMax(), fileStats.getMin()); // 占用空间统计 LongSummaryStatistics spaceStats = stats.getUsedSpaceStats(); System.out.printf("总占用空间: %d字节, 最大单仓库占用: %d字节, 最小单仓库占用: %d字节%n", spaceStats.getSum(), spaceStats.getMax(), spaceStats.getMin()); }
内容的提问来源于stack exchange,提问作者carlitos081
相关产品推荐
相关产品推荐

