Stream流groupby分组及分组后求和

1、分组后额外操作比较麻烦,需要提供额外的参数如Collectors.mapping()、Collectors.reducing()等。
2、求和有两种方式,一种就是正常groupby分组之后,用Collectors.reducing()合并计算;一种是通过toMap的形式转成map,当key冲突时走处理策略进行求和。

public class Test {

    public static void main(String[] args) {
        List<User> list = Arrays.asList(
                new User("小赵", "男",20, new BigDecimal("123.33"), DateUtil.parseDateTime("2014-5-18 23:12:29")),
                new User("小钱", "女",9, new BigDecimal("89.12"), DateUtil.parseDateTime("2023-2-18 06:45:12")),
                new User("小孙", "女",18, new BigDecimal("280.28"), DateUtil.parseDateTime("2009-3-31 16:33:45")),
                new User("小李", "男",13, new BigDecimal("1000.99"), DateUtil.parseDateTime("1992-12-4 10:48:08"))
        );
        list.forEach(System.out::println);
        System.out.println();

        //分组
        Map<String, List<User>> map = list.stream().collect(Collectors.groupingBy(User::getSex));
        for (Map.Entry<String, List<User>> entry : map.entrySet()) {
            System.out.println(entry.getKey() + "分组:");
            entry.getValue().forEach(System.out::println);
        }
        System.out.println();

        //分组并取某个字段
        Map<String, List<Date>> birthdayMap = list.stream().collect(Collectors.groupingBy(
                User::getSex, Collectors.mapping(User::getBirthday, Collectors.toList())
        ));
        for (Map.Entry<String, List<Date>> entry : birthdayMap.entrySet()) {
            System.out.println(entry.getKey() + "分组:");
            entry.getValue().forEach(System.out::println);
        }
        System.out.println();

        //分组求和
        Map<String, BigDecimal> moneyMap1 = list.stream().collect(Collectors.groupingBy(
                User::getSex, Collectors.reducing(BigDecimal.ZERO, User::getMoney, BigDecimal::add)
        ));
        for (Map.Entry<String, BigDecimal> entry : moneyMap1.entrySet()) {
            System.out.println(entry.getKey() + "分组:"+entry.getValue());
        }
        System.out.println();

        //分组求和 toMap形式
        Map<String, BigDecimal> moneyMap2 = list.stream().collect(Collectors.toMap(User::getSex, User::getMoney, BigDecimal::add));
        for (Map.Entry<String, BigDecimal> entry : moneyMap2.entrySet()) {
            System.out.println(entry.getKey() + "分组:" + entry.getValue());
        }
        System.out.println();
    }

}

@Data
@ToString
@AllArgsConstructor
class User {

    private String name;

    private String sex;

    private Integer age;

    private BigDecimal money;

    private Date birthday;

}
User(name=小赵, sex=男, age=20, money=123.33, birthday=2014-05-18 23:12:29)
User(name=小钱, sex=女, age=9, money=89.12, birthday=2023-02-18 06:45:12)
User(name=小孙, sex=女, age=18, money=280.28, birthday=2009-03-31 16:33:45)
User(name=小李, sex=男, age=13, money=1000.99, birthday=1992-12-04 10:48:08)

女分组:
User(name=小钱, sex=女, age=9, money=89.12, birthday=2023-02-18 06:45:12)
User(name=小孙, sex=女, age=18, money=280.28, birthday=2009-03-31 16:33:45)
男分组:
User(name=小赵, sex=男, age=20, money=123.33, birthday=2014-05-18 23:12:29)
User(name=小李, sex=男, age=13, money=1000.99, birthday=1992-12-04 10:48:08)

女分组:
2023-02-18 06:45:12
2009-03-31 16:33:45
男分组:
2014-05-18 23:12:29
1992-12-04 10:48:08

女分组:369.40
男分组:1124.32

女分组:369.40
男分组:1124.32

觉得内容还不错?打赏个钢镚鼓励鼓励!!👍