用collectors.groupingby统计全国业务热力图,核心是地理字段标准化(统一为行政区划代码或规范名称)和多级嵌套分组(省→市→区),支持自定义聚合逻辑与前端适配格式。

用 Collectors.groupingBy 统计全国业务热力图,核心是把地理位置(如省、市、区)作为分组键,对业务数据(如订单数、交易额)做聚合。关键不在“怎么分组”,而在“怎么让地理层级可比、可聚合、可下钻”。
地理字段需标准化为统一粒度
原始数据中地址可能是“北京市朝阳区建国路8号”“北京朝阳区”“BJCYQ”,直接分组会散列。必须先清洗成标准行政编码或规范名称:
- 推荐使用国家统计局最新《行政区划代码》(如110105代表北京市朝阳区),用编码分组最稳定
- 若只有中文名,需统一名称:将“北京市”“北京”“京”归一为“北京市”,“朝阳区”“朝阳”归一为“朝阳区”
- 避免直接对完整地址字符串分组——重复率低、无法聚合到省级维度
按多级地理维度嵌套分组
热力图常需省→市→区三级下钻。可用嵌套 groupingBy 实现:
Map<string map long>> provinceCityCount = dataList.stream()
.collect(Collectors.groupingBy(
data -> data.getProvince(), // 如"广东省"
Collectors.groupingBy(
data -> data.getCity(), // 如"深圳市"
Collectors.counting()
)
));</string>
这样得到的是 Map>,前端可逐层展开渲染热力层级。
聚合值不只限于计数,支持自定义统计逻辑
热力强度常是交易额、用户数、增长率等。用 Collectors.collectingAndThen 或自定义 Collector 做复合计算:
- 按省份统计总交易额:
Collectors.summingDouble(data -> data.getAmount()) - 统计各市平均客单价:
Collectors.averagingDouble(data -> data.getAmount() / data.getOrderCount()) - 带条件过滤(如仅统计本月活跃城市):
Collectors.filtering(data -> data.getDate().isAfter(earlyThisMonth), Collectors.counting())
输出结构适配前端热力图组件
主流地图库(如 ECharts、Mapbox)通常要求数据格式为数组,每项含 name(地名)、value(数值):
List<map object>> heatmapData = provinceCityCount.entrySet().stream()
.flatMap(provinceEntry -> provinceEntry.getValue().entrySet().stream()
.map(cityEntry -> {
Map<string object> item = new HashMap();
item.put("name", provinceEntry.getKey() + cityEntry.getKey()); // "广东省深圳市"
item.put("value", cityEntry.getValue());
return item;
})
)
.collect(Collectors.toList());</string></map>
也可按需生成 GeoJSON 格式,将数值挂载到对应行政区 geometry 的 properties 中。
不复杂但容易忽略:地理统计前务必校验数据覆盖完整性——比如某省无数据,不代表业务为零,可能是地址未识别或上报缺失。建议同步补全空值占位,再传给前端做等宽色阶渲染。










