0
点赞
收藏
分享

微信扫一扫

java steam 使用指南-------groupingBy进阶用法

追梦人的自留地 2022-01-26 阅读 194

文章目录

前言

刚开始我只会使用普通的for、while循环,最多就增强for循环,后来在项目上看到其他同事在用,看起来很新颖、简洁的样子,然后我也开始尝试使用,用顺手之后发现是真的香。在使用的过程中,有些时候,不能完全实现自己所想的,也没少百度,所以呢,就想着把这些稍微高级一点、难一点的用法记录下来,

数据准备:

public class BlogMain1 {

    @Data
    @AllArgsConstructor
    static class User{
        private String username;
        private String gender;
        private String group;
        private Integer age;
    }

    @Data
    @AllArgsConstructor
    static class Group {
        private String name;
        private String desc;
    }

    private List<User> users = new ArrayList<User>(){{
        add(new User("张无忌","男","明教",23));
        add(new User("金毛狮王--谢逊","男","明教",47));
        add(new User("紫衫龙王--黛绮丝","女","明教",32));
        add(new User("白眉鹰王--殷天正","男","明教",38));
        add(new User("青翼蝠王--韦一笑","男","明教",35));
        add(new User("张三丰","男","武当",56));
        add(new User("宋远桥","男","武当",42));
        add(new User("张翠山","男","武当",41));
        add(new User("殷梨亭","男","武当",37));
        add(new User("灭绝师太","女","峨眉",51));
        add(new User("周芷若","女","峨眉",21));
        add(new User("宋青书","男","峨眉",22));
        add(new User("圆真","男","少林",35));
        add(new User("空智","男","少林",47));
    }};
}

一. 分组 groupingBy

基础用法

1. 按照某个属性分组

 // key是门派名称,value是门派里面所有的人
 Map<String, List<User>> collect = users.stream().collect(Collectors.groupingBy(User::getGroup));
 // {武当=[BlogMain1.User(username=张三丰, gender=男, group=武当, age=56), BlogMain1.User(username=宋远桥, gender=男, group=武当, age=42), BlogMain1.User(username=张翠山, gender=男, group=武当, age=41), BlogMain1.User(username=殷梨亭, gender=男, group=武当, age=37)], 明教=[BlogMain1.User(username=张无忌, gender=男, group=明教, age=23), BlogMain1.User(username=金毛狮王--谢逊, gender=男, group=明教, age=47), BlogMain1.User(username=紫衫龙王--黛绮丝, gender=女, group=明教, age=32), BlogMain1.User(username=白眉鹰王--殷天正, gender=男, group=明教, age=38), BlogMain1.User(username=青翼蝠王--韦一笑, gender=男, group=明教, age=35)], 峨眉=[BlogMain1.User(username=灭绝师太, gender=女, group=峨眉, age=51), BlogMain1.User(username=周芷若, gender=女, group=峨眉, age=21), BlogMain1.User(username=宋青书, gender=男, group=峨眉, age=22)], 少林=[BlogMain1.User(username=圆真, gender=男, group=少林, age=35), BlogMain1.User(username=空智, gender=男, group=少林, age=47)]}

2. 分组统计

// key是门派名称,value是门派人数
Map<String, Long> collect1 = users.stream().collect(Collectors.groupingBy(User::getGroup, Collectors.counting()));
// {武当=4, 明教=5, 峨眉=3, 少林=2}

3. 分组求和

// key是门派名称,value是门派人年龄之和
 Map<String, Long> collect2 = users.stream().collect(Collectors.groupingBy(User::getGroup, Collectors.summingLong(User::getAge)));
// {武当=176, 明教=175, 峨眉=94, 少林=82}

4. 自定义分组条件------按姓名长度分组

// 按照姓名长度分组
Map<Integer, List<User>> collect3 = users.stream().collect(Collectors.groupingBy(x -> x.username.length()));
// {2=[BlogMain1.User(username=圆真, gender=男, group=少林, age=35), BlogMain1.User(username=空智, gender=男, group=少林, age=47)], 3=[BlogMain1.User(username=张无忌, gender=男, group=明教, age=23), BlogMain1.User(username=张三丰, gender=男, group=武当, age=56), BlogMain1.User(username=宋远桥, gender=男, group=武当, age=42), BlogMain1.User(username=张翠山, gender=男, group=武当, age=41), BlogMain1.User(username=殷梨亭, gender=男, group=武当, age=37), BlogMain1.User(username=周芷若, gender=女, group=峨眉, age=21), BlogMain1.User(username=宋青书, gender=男, group=峨眉, age=22)], 4=[BlogMain1.User(username=灭绝师太, gender=女, group=峨眉, age=51)], 8=[BlogMain1.User(username=金毛狮王--谢逊, gender=男, group=明教, age=47)], 9=[BlogMain1.User(username=紫衫龙王--黛绮丝, gender=女, group=明教, age=32), BlogMain1.User(username=白眉鹰王--殷天正, gender=男, group=明教, age=38), BlogMain1.User(username=青翼蝠王--韦一笑, gender=男, group=明教, age=35)]}

5. 自定义分组条件------按照多个字段分组

// 多个属性分组,按照门派和性别分组
Map<String, List<User>> collect4 = users.stream().collect(Collectors.groupingBy(x -> x.getGroup() + "_" + x.getGender()));
// {少林_男=[BlogMain1.User(username=圆真, gender=男, group=少林, age=35), BlogMain1.User(username=空智, gender=男, group=少林, age=47)], 明教_男=[BlogMain1.User(username=张无忌, gender=男, group=明教, age=23), BlogMain1.User(username=金毛狮王--谢逊, gender=男, group=明教, age=47), BlogMain1.User(username=白眉鹰王--殷天正, gender=男, group=明教, age=38), BlogMain1.User(username=青翼蝠王--韦一笑, gender=男, group=明教, age=35)], 峨眉_男=[BlogMain1.User(username=宋青书, gender=男, group=峨眉, age=22)], 武当_男=[BlogMain1.User(username=张三丰, gender=男, group=武当, age=56), BlogMain1.User(username=宋远桥, gender=男, group=武当, age=42), BlogMain1.User(username=张翠山, gender=男, group=武当, age=41), BlogMain1.User(username=殷梨亭, gender=男, group=武当, age=37)], 明教_女=[BlogMain1.User(username=紫衫龙王--黛绮丝, gender=女, group=明教, age=32)], 峨眉_女=[BlogMain1.User(username=灭绝师太, gender=女, group=峨眉, age=51), BlogMain1.User(username=周芷若, gender=女, group=峨眉, age=21)]}

高级用法

只是个人感觉比上面的高级一些,可能在大佬看来本质上都一样,只是更复杂了一点点。

1. 改变分组后的key和value

在上面的分组中,key还好,在4和5自定义条件分组中,改变了key。但是value呢?好像都是定死了,普通的分组就是该对象的集合,求和、统计就是一个数字,能不能我自己来规定返回的value类型呢?比如我要按照门派分组,得到每个门派里面每个人的名字,不需要其他的性别、年龄信息

// 按照门派分组,分组后 key 为Group对象, value变成String名字
Map<Group, List<String>> collect2 = users.stream()
                .collect(Collectors.groupingBy(x -> new Group(x.getGroup(), x.getGroup() + "的描述"),
                        Collectors.mapping(User::getUsername, Collectors.toCollection(ArrayList::new))));
// {BlogMain1.Group(name=明教, desc=明教的描述)=[张无忌, 金毛狮王--谢逊, 紫衫龙王--黛绮丝, 白眉鹰王--殷天正, 青翼蝠王--韦一笑], BlogMain1.Group(name=武当, desc=武当的描述)=[张三丰, 宋远桥, 张翠山, 殷梨亭], BlogMain1.Group(name=少林, desc=少林的描述)=[圆真, 空智], BlogMain1.Group(name=峨眉, desc=峨眉的描述)=[灭绝师太, 周芷若, 宋青书]}

2. 多级分组

先按照一个条件分组,在分组的基础上再按照另一个条件分组

// 多级分组,先按照门派分组,门派里面再按照名字长度分组
Map<Group, Map<Integer, List<User>>> collect3 = users.stream().collect(Collectors.groupingBy(x -> new Group(x.getGroup(), x.getGroup() + "的描述"),
                Collectors.groupingBy(x -> x.username.length())));
// {BlogMain1.Group(name=明教, desc=明教的描述)={3=[BlogMain1.User(username=张无忌, gender=男, group=明教, age=23)], 8=[BlogMain1.User(username=金毛狮王--谢逊, gender=男, group=明教, age=47)], 9=[BlogMain1.User(username=紫衫龙王--黛绮丝, gender=女, group=明教, age=32), BlogMain1.User(username=白眉鹰王--殷天正, gender=男, group=明教, age=38), BlogMain1.User(username=青翼蝠王--韦一笑, gender=男, group=明教, age=35)]}, BlogMain1.Group(name=武当, desc=武当的描述)={3=[BlogMain1.User(username=张三丰, gender=男, group=武当, age=56), BlogMain1.User(username=宋远桥, gender=男, group=武当, age=42), BlogMain1.User(username=张翠山, gender=男, group=武当, age=41), BlogMain1.User(username=殷梨亭, gender=男, group=武当, age=37)]}, BlogMain1.Group(name=少林, desc=少林的描述)={2=[BlogMain1.User(username=圆真, gender=男, group=少林, age=35), BlogMain1.User(username=空智, gender=男, group=少林, age=47)]}, BlogMain1.Group(name=峨眉, desc=峨眉的描述)={3=[BlogMain1.User(username=周芷若, gender=女, group=峨眉, age=21), BlogMain1.User(username=宋青书, gender=男, group=峨眉, age=22)], 4=[BlogMain1.User(username=灭绝师太, gender=女, group=峨眉, age=51)]}}

3. 我在项目中的使用例子

在这里插入图片描述

暂时就想到这么多,欢迎补充

举报

相关推荐

0 条评论