首页 > 编程语言 >【转载】Java stream对List对象进行分组聚合操作:求和、平均值、最大值、最小值,BigDecimal求和

【转载】Java stream对List对象进行分组聚合操作:求和、平均值、最大值、最小值,BigDecimal求和

时间:2022-11-23 16:34:45浏览次数:48  
标签:map Java BigDecimal stream get 求和 toString new

package com.kabka.test;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * List 分组求和
 *
 * @author yunnuo
 * @since 2022-06-11
 */
@Slf4j
public class ListGroupSumTest {

    @Test
    public void testSum() {
        List<Map<String, Object>> mapList = new ArrayList<>();

        String[] names = {"张三", "李四", "王五"};

        // 循环mock 随机值
        for (int i = 0; i < 10; i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", names[new Random().nextInt(3)]);
            map.put("value", i);
            map.put("money", new BigDecimal(new Random().nextFloat() * i).setScale(4, BigDecimal.ROUND_DOWN));
            mapList.add(map);
        }
        log.info("原始未分组mapList:{}", JSONUtil.toJsonStr(mapList));
        // 通过name进行分组
        Map<String, List<Map<String, Object>>> mapListGroupByName = mapList.stream().collect(Collectors.groupingBy(map -> map.get("name").toString()));
        log.info("分组后:{}", JSONUtil.toJsonStr(mapListGroupByName));

        List<Map<String, Object>> groupMapList = new ArrayList<>();
        // 对分组数据进行求和操作
        mapListGroupByName.forEach((name, mapByNameList) -> {
            HashMap<String, Object> reMap = new HashMap<>();
            // 求和
            int sum = mapByNameList.stream().mapToInt(map -> Integer.parseInt(map.get("value").toString())).sum();
            // 最大值
            OptionalInt maxOpt = mapByNameList.stream().mapToInt(map -> Integer.parseInt(map.get("value").toString())).max();
            // 最小值
            Long count = mapByNameList.stream().mapToInt(map -> Integer.parseInt(map.get("value").toString())).count();
            // 平均值
            OptionalDouble averageOpt = mapByNameList.stream().mapToInt(map -> Integer.parseInt(map.get("value").toString())).average();

            BigDecimal sumMoney = new BigDecimal(0);
            // BigDecimal 进行 求和
            for (Map<String, Object> map : mapByNameList) {
                BigDecimal money = new BigDecimal(map.get("money").toString());
                sumMoney= sumMoney.add(money);
            }

            reMap.put("name", name);
            reMap.put("sum", sum);
            reMap.put("count", count);
            reMap.put("sumMoney", sumMoney);
            maxOpt.ifPresent(max -> reMap.put("max", max));
            averageOpt.ifPresent(average -> reMap.put("average", average));
            groupMapList.add(reMap);
        });
        log.info("分组后聚合List:{}", JSONUtil.toJsonStr(groupMapList));
    }
}

解析

本博主采用map来代替DTO,进行对map对象->mapList循环随机赋值,属性分别为:name、value、money
在这里插入图片描述
然后对mapList 通过name属性进行分组 生成新的map为 mapListGroupByName,其中生成的map的key是采用分组的name作为key,相同name的map则放在一起生成mapListGroupByName的value值 :List<Map<String, Object>>,从下图可看出
其中分组李四有两条数据,张三有五条, 王五有三条
在这里插入图片描述

后面我们将分组后的map:mapListGroupByName进行聚合操作:求和、平均值、最大值、最小值和BigDecimal求和形成一个新的 List<Map<String, Object>>对象groupMapList,如下图所示
在这里插入图片描述
其中Java8新特性中的stream操作可以对数据进行直接求和、平均值、最大值、最小值等,感兴趣的小伙伴可以自行看api,博主这边还对BigDecimal类型的数据进行求和了,所以一般涉及到金钱等重要数据采用BigDecimal来存储的话,也可以像博主一样进行循环求和操作。

// 求和
int sum = mapByNameList.stream().mapToInt(map -> Integer.parseInt(map.get("value").toString())).sum();
// 最大值
OptionalInt maxOpt = mapByNameList.stream().mapToInt(map -> Integer.parseInt(map.get("value").toString())).max();
// 最小值
Long count = mapByNameList.stream().mapToInt(map -> Integer.parseInt(map.get("value").toString())).count();
// 平均值
OptionalDouble averageOpt = mapByNameList.stream().mapToInt(map -> Integer.parseInt(map.get("value").toString())).average();

BigDecimal sumMoney = new BigDecimal(0);
// BigDecimal 进行 求和
for (Map<String, Object> map : mapByNameList) {
    BigDecimal money = new BigDecimal(map.get("money").toString());
    sumMoney= sumMoney.add(money);
}
————————————————
版权声明:本文为CSDN博主「小诺大人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ayunnuo/article/details/125232239

标签:map,Java,BigDecimal,stream,get,求和,toString,new
From: https://www.cnblogs.com/haohaiyou/p/16918751.html

相关文章

  • Java特性和优势
    简单性与C语言不同,Java是一种面向对象编程的语言,他的底层借鉴了C++语言但又不是完全相同,Java语言并不支持多继承、指针、goto语句、操作符重载、头文件等,但其语法基于C语......
  • java web开发(和vue联合开发)
        前面我们谈到了很多次vue,也说到了vue的很多优点。比如说,vue实现了mvc中全部v的功能,也就是view的部分。这样,后端开发就变得很简单,前后端之间只要实现json数据的......
  • Java + Lua = 王炸!!
    我们写东西的时候总会遇到lua中要调用java代码,当然这个用JNI肯定是可以做到的,但是有更加方便的办法—LuaJavaBridge。一、luaj主要特征*可以从Lua调用JavaClassS......
  • Java 注解和反射(一)注解
    一,注解(Annotation)顾名思义,注解,注释解释什么是注解?··Annotation是从JDK5.0开始引入的技术··Annotation的作用:1.不是程序本身,可以对程序做出解释(这一点和注释......
  • 多个List,合并,去重操作。用stream
    例,用户1有“admin”,"test"两个角色,用户2有“test”,上代码List<TestUser>list=newArrayList<>();TestUseruser1=newTestUser();user1.setRoles(Arrays.asList("......
  • java web开发(aop编程)
        刚开始看到aop的时候,了解到它是面向切片,觉得还是挺拗口的。不知道应该怎么去理解怎么这么一个概念。后来想了一想,不如先看范例,直接从实例去理解aop或许更容易一......
  • java web开发(mysql开发)
        选择了java作为项目开发语言,一般就不再会选择商业数据库了,比如说sqlserver,oracle之类的,除非是项目有特殊需求。大多数情况下,开发者都会选择mysql作为应用数据......
  • java web开发(第一个spring程序)
        提到javaweb编程,好像spring就躲不开了。一般认为,spring有两个特征,分别是ioc、aop。两个英文单词的中文解释都比较拗口,一个称之为控制反转,一个是面向切面。对于......
  • java web开发(servlet传递数据给jsp)
        实际开发中,servlet多用于controller,jsp多用于view。之前,我们谈过了怎么把数据从jsp传递给servlet,即采用form+action的方法来完成这一目标。今天可以继续讨论下,s......
  • java web开发(jsp传递数据给servlet)
        有了servlet,有了jsp,其实就已经可以做很多的事情了。比如说表单的制作等等。在实际项目中,表单、表格都是很常见的输入选项。一个常见的场景,就是客户在输入数据之......