java8 list map 聚合求和

目标:

统计地市的总的完成数量,并根据总数来排序。

要把下面的数据:

复制代码
[
	{
		"city_name": "南京市",
		"carrier_id": "2",
		"carrier_name": "移动",
		"city_id": "0",
		"finish_num": 14
	},
	{
		"city_name": "南京市",
		"carrier_id": "5",
		"carrier_name": "移动转售企业",
		"city_id": "0",
		"finish_num": 1
	},
	{
		"city_name": "南京市",
		"carrier_id": "6",
		"carrier_name": "长城宽带",
		"city_id": "0",
		"finish_num": 1
	},
	{
		"city_name": "南京市",
		"carrier_id": "7",
		"carrier_name": "增值电信企业",
		"city_id": "0",
		"finish_num": 1
	},
	{
		"city_name": "无锡市",
		"carrier_id": "1",
		"carrier_name": "电信",
		"city_id": "1",
		"finish_num": 3
	},
	{
		"city_name": "镇江市",
		"carrier_id": "1",
		"carrier_name": "电信",
		"city_id": "10",
		"finish_num": 1
	}, 
	{
		"city_name": "常州市",
		"carrier_id": "2",
		"carrier_name": "移动",
		"city_id": "3",
		"finish_num": 1
	},
	{
		"city_name": "常州市",
		"carrier_id": "1",
		"carrier_name": "电信",
		"city_id": "3",
		"finish_num": 1
	},
	{
		"city_name": "常州市",
		"carrier_id": "5",
		"carrier_name": "移动转售企业",
		"city_id": "3",
		"finish_num": 1
	} 
]

目标格式:

java 复制代码
[
	{
		"city_name": "南京市",
		"total": 17,
		"city_id": "0"
	},
	{
		"city_name": "常州市",
		"total": 5,
		"city_id": "3"
	},
	{
		"city_name": "无锡市",
		"total": 3,
		"city_id": "1"
	}
]

处理:

模拟数据:

java 复制代码
public static List<Map<String, Object>> initData() {
        String data = "[\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"南京市\",\n" +
                "\t\t\"carrier_id\": \"2\",\n" +
                "\t\t\"carrier_name\": \"移动\",\n" +
                "\t\t\"city_id\": \"0\",\n" +
                "\t\t\"finish_num\": 14\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"南京市\",\n" +
                "\t\t\"carrier_id\": \"5\",\n" +
                "\t\t\"carrier_name\": \"移动转售企业\",\n" +
                "\t\t\"city_id\": \"0\",\n" +
                "\t\t\"finish_num\": 1\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"南京市\",\n" +
                "\t\t\"carrier_id\": \"6\",\n" +
                "\t\t\"carrier_name\": \"长城宽带\",\n" +
                "\t\t\"city_id\": \"0\",\n" +
                "\t\t\"finish_num\": 1\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"南京市\",\n" +
                "\t\t\"carrier_id\": \"7\",\n" +
                "\t\t\"carrier_name\": \"增值电信企业\",\n" +
                "\t\t\"city_id\": \"0\",\n" +
                "\t\t\"finish_num\": 1\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"无锡市\",\n" +
                "\t\t\"carrier_id\": \"1\",\n" +
                "\t\t\"carrier_name\": \"电信\",\n" +
                "\t\t\"city_id\": \"1\",\n" +
                "\t\t\"finish_num\": 3\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"镇江市\",\n" +
                "\t\t\"carrier_id\": \"1\",\n" +
                "\t\t\"carrier_name\": \"电信\",\n" +
                "\t\t\"city_id\": \"10\",\n" +
                "\t\t\"finish_num\": 1\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"宿迁市\",\n" +
                "\t\t\"carrier_id\": \"3\",\n" +
                "\t\t\"carrier_name\": \"联通\",\n" +
                "\t\t\"city_id\": \"12\",\n" +
                "\t\t\"finish_num\": 1\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"外省\",\n" +
                "\t\t\"carrier_id\": \"1\",\n" +
                "\t\t\"carrier_name\": \"电信\",\n" +
                "\t\t\"city_id\": \"13\",\n" +
                "\t\t\"finish_num\": 3\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"徐州市\",\n" +
                "\t\t\"carrier_id\": \"3\",\n" +
                "\t\t\"carrier_name\": \"联通\",\n" +
                "\t\t\"city_id\": \"2\",\n" +
                "\t\t\"finish_num\": 2\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"常州市\",\n" +
                "\t\t\"carrier_id\": \"2\",\n" +
                "\t\t\"carrier_name\": \"移动\",\n" +
                "\t\t\"city_id\": \"3\",\n" +
                "\t\t\"finish_num\": 1\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"常州市\",\n" +
                "\t\t\"carrier_id\": \"1\",\n" +
                "\t\t\"carrier_name\": \"电信\",\n" +
                "\t\t\"city_id\": \"3\",\n" +
                "\t\t\"finish_num\": 1\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"常州市\",\n" +
                "\t\t\"carrier_id\": \"5\",\n" +
                "\t\t\"carrier_name\": \"移动转售企业\",\n" +
                "\t\t\"city_id\": \"3\",\n" +
                "\t\t\"finish_num\": 1\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"常州市\",\n" +
                "\t\t\"carrier_id\": \"6\",\n" +
                "\t\t\"carrier_name\": \"长城宽带\",\n" +
                "\t\t\"city_id\": \"3\",\n" +
                "\t\t\"finish_num\": 1\n" +
                "\t},\n" +
                "\t{\n" +
                "\t\t\"city_name\": \"常州市\",\n" +
                "\t\t\"carrier_id\": \"7\",\n" +
                "\t\t\"carrier_name\": \"增值电信企业\",\n" +
                "\t\t\"city_id\": \"3\",\n" +
                "\t\t\"finish_num\": 1\n" +
                "\t}\n" +
                "]";

        return changeFormat(data);

    }

    private static List<Map<String,Object>> changeFormat(String areaInfo){
        JSONArray areaArr = JSONArray.parseArray(areaInfo);
        return ListUtils.emptyIfNull(areaArr).stream().map(e -> (JSONObject) e)
                .map(e -> (Map<String, Object>)JSONObject.parseObject( e.toJSONString())).collect(Collectors.toList());
    }

方式一: 分布处理

先根据市进行聚合,再根据数量进行求和

java 复制代码
  Map<String, List<Map<String, Object>>> cityGroup = ListUtils.emptyIfNull(cityCarrier).stream()
                .collect(Collectors.groupingBy(e -> e.get("city_id").toString()));

  Map<String, Integer> citySumMap = MapUtils.emptyIfNull(cityGroup).entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, t -> 
ListUtils.emptyIfNull(t.getValue()).stream().mapToInt(f -> 
MapUtils.getInteger(f, "finish_num")).sum()));
        System.out.println(citySumMap);

能分步处理,说明可以聚合到一起处理

方式二:聚合处理

java 复制代码
Map<String, IntSummaryStatistics> citySumMap2 = 
ListUtils.emptyIfNull(cityCarrier).stream()          
.collect(Collectors.groupingBy(e -> e.get("city_id").toString(),                  
Collectors.summarizingInt(f -> MapUtils.getInteger(f, "finish_num"))));

汇总:

java 复制代码
public static void main(String[] args) {
        List<Map<String, Object>> cityCarrier = initData();
        Map<String, String> cityNameMap = ListUtils.emptyIfNull(cityCarrier).stream().collect(Collectors.toMap(e -> MapUtils.getString(e, "city_id"), f -> MapUtils.getString(f, "city_name"), (x, y) -> x));

        Map<String, IntSummaryStatistics> citySumMap2 = ListUtils.emptyIfNull(cityCarrier).stream()
                .collect(Collectors.groupingBy(e -> e.get("city_id").toString(),
                        Collectors.summarizingInt(f -> MapUtils.getInteger(f, "finish_num"))));
        List<Map<String, Object>> cityCountData = MapUtils.emptyIfNull(cityNameMap).entrySet().stream().map(e -> {
            String key = e.getKey();
            Map<String, Object> temp = new HashMap<>();
            temp.put("city_id", key);
            temp.put("city_name", e.getValue());
            temp.put("total", citySumMap2.get(key).getSum());
            return temp;
        }).collect(Collectors.toList());
        List<Map<String, Object>> result = ListUtils.emptyIfNull(cityCountData).stream().sorted((c1, c2) -> MapUtils.getDouble(c2, "total").compareTo(MapUtils.getDouble(c1, "total"))).collect(Collectors.toList());
        System.out.println(JSON.toJSONString(result));
    }

输出:

java 复制代码
[
	{
		"city_name": "南京市",
		"total": 17,
		"city_id": "0"
	},
	{
		"city_name": "常州市",
		"total": 5,
		"city_id": "3"
	},
	{
		"city_name": "无锡市",
		"total": 3,
		"city_id": "1"
	},
	{
		"city_name": "外省",
		"total": 3,
		"city_id": "13"
	},
	{
		"city_name": "徐州市",
		"total": 2,
		"city_id": "2"
	},
	{
		"city_name": "宿迁市",
		"total": 1,
		"city_id": "12"
	},
	{
		"city_name": "镇江市",
		"total": 1,
		"city_id": "10"
	}
]

这样就达到目的了。

总结:

list map 聚合求和,要熟悉第二种方式处理方式,写法比较简便。想不到就用第一种的方式,肯定可以。

相关推荐
铉铉这波能秀2 小时前
LeetCode Hot100数据结构背景知识之列表(List)Python2026新版
数据结构·leetcode·list
燃于AC之乐9 小时前
深入解剖STL List:从源码剖析到相关接口实现
c++·stl·list·源码剖析·底层实现
田野追逐星光1 天前
STL容器list的模拟实现
开发语言·c++·list
浪客灿心3 天前
list_stack_queue
数据结构·list
HIT_Weston3 天前
121、【Ubuntu】【Hugo】首页板块配置:list 模板(一)
linux·ubuntu·list
10km4 天前
Spring Boot 环境下使用 Map<String, MultipartFile> 实现文件上传功能
java·spring boot·mock·map·multipartfile
苏宸啊4 天前
list底层实现
c++·list
波波0074 天前
每日一题:在 .NET 中遍历集合(如 List<T>、数组、字典)的过程中进行增删改查会不会有影响?可能引发哪些问题?实际开发中应如何避免?
前端·list
以太浮标4 天前
华为eNSP模拟器综合实验之- 前缀列表(IP Prefix-list --匹配和控制路由信息的强大工具)
tcp/ip·华为·智能路由器·list
jiunian_cn5 天前
【Redis】list数据类型相关指令
数据库·redis·list