List集合使用groupBy实现根据实体属性进行快速分组

Java技术 潘老师 3年前 (2021-08-04) 2948 ℃ (0) 扫码查看

List集合中一般有很多实体对象,每个对象都有自己的属性,有时我们需要将具备某个相同属性的对象进行分组处理,传统写法比较好理解也容易实现,但代码量比较大不太优美,而且要多次循环,而Java8给我们提供了新方法,一行代码搞定分组,不仅让潘老师体会到了什么叫优雅地写代码,更体会到了要与时俱进,不然写的代码真是越来越out了!下面,潘老师来对比下这两种实现方式的差距。

一、前期准备

首先我们新建一个User类,代码如下:

public class User {
    private String name;
    private String sex;
    private String grade;

    public User(String name, String sex,String grade) {

        this.name = name;
        this.sex = sex;
        this.grade = grade;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {

        this.name = name;
    }

    public String getSex() {

        return sex;
    }

    public void setSex(String sex) {

        this.sex = sex;
    }

    public String getGrade() {

        return grade;
    }

    public void setGrade(String grade) {

        this.grade = grade;
    }

    @Override
    public String toString() {

        return "User{" + "name='" + name + '\'' + ", sex='" + sex + '\'' + ", grade='" + grade + '\'' + '}';
    }
}

二、传统写法

我们先使用传统写法将List集合中的User按照sex属性进行分组:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {

    public static void main(String[] args) {

        List<User> users = new ArrayList<>();
        users.add(new User("小明","男","1班"));
        users.add(new User("小红","女","1班"));
        users.add(new User("小张","男","2班"));
        users.add(new User("小兰","女","1班"));
        users.add(new User("小紫","女","2班"));

        Map<String,List<User>> userMap = new HashMap<>();
        for (User user : users) {
            String name = user.getName();
            if (userMap.containsKey(name)) {
                userMap.get(name).add(user);
            }else {
                List<User> list = new ArrayList<>();
                list.add(user);
                userMap.put(name,list);
            }
        }
        System.out.println(userMap);
    }
}

三、优雅写法

1、我们先根据sex来分组,代替上面的传统写法:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Test {

    public static void main(String[] args) {

        List<User> users = new ArrayList<>();
        users.add(new User("小明","男","1班"));
        users.add(new User("小红","女","1班"));
        users.add(new User("小张","男","2班"));
        users.add(new User("小兰","女","1班"));
        users.add(new User("小紫","女","2班"));
        // 核心代码(返回Map集合,key就是分组的属性,value就是分组后的集合)
        Map<String, List<User>> userMap = users.stream().collect(Collectors.groupingBy(User::getSex));
        System.out.println(userMap);

    }
}

输出结果:

2、groupBy还支持嵌套分组,我们可以实现先根据sex分组,对分组后的每个List数据再根据grade分组,其代码如下:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Test {

    public static void main(String[] args) {

        List<User> users = new ArrayList<>();
        users.add(new User("小明","男","1班"));
        users.add(new User("小红","女","1班"));
        users.add(new User("小张","男","2班"));
        users.add(new User("小兰","女","1班"));
        users.add(new User("小紫","女","2班"));
        // 核心代码(返回Map集合,也是嵌套的,最外层key就是sex,内层map的key是grade)
        Map<String,Map<String,List<User>>> userMap = users.stream().collect(Collectors.groupingBy(User::getSex,Collectors.groupingBy(User::getGrade)));
        System.out.println(userMap);

    }

输出结果:

好了,以后再也不用再为集合分组闹心了,也就一行代码的事儿!
Java8Stream是新特性,除了collect还有很多对集合高阶操作的方法,具体的可以参考:菜鸟教程 Java8 Stream


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/java/3425.html
喜欢 (4)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】