java list分组成map

2023-11-03

将List集合分成分组成map在工作中常常会遇到。这里我总结了两种方式:Lambda表达式方式和传统方式。

前期准备

先创建一个User类,用于分类

class User{
    private Integer age;

    private String name;

    public User(Integer age, String name) {
        this.age = age;
        this.name = name;
    }
  // 省略get、set方法
    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

测试类中写个打印方法,一目了然就可以看到分组

void printMap(Map<Integer, List<User>> map){
        for (Map.Entry<Integer, List<User>> entry : map.entrySet()) {
            Integer key = entry.getKey();
            List<User> value = entry.getValue();
            System.out.println("key="+key+", value="+value);
        }
    }

实操

先在测试类中创建一个User集合并初始化

public class CommonTest {

    private final List<User> list;
    {
        list = new ArrayList<>();
        list.add(new User(16, "16_1"));
        list.add(new User(16, "16_2"));
        list.add(new User(16, "16_3"));

        list.add(new User(12, "12_1"));
        list.add(new User(12, "12_2"));
        list.add(new User(12, "12_3"));

        list.add(new User(14, "14_1"));
        list.add(new User(14, "14_2"));
        list.add(new User(14, "14_3"));
    }
}

Lambda表达式方式

Lambda表达式主要用到的是Collectors#groupingBy和partitioningBy。二者又有所不同:

  • groupingBy 可以将list按条件分成多组,返回的对象Map<K, List<T>>形式
  • partitioningBy 只能将list按条件分为两组,返回的对象是Map<Boolean, List<T>>形式

groupingBy分组

话不多说看代码

@Test
public void testGroupingBy(){
    Map<Integer, List<User>> map = list.stream()
            .collect(Collectors.groupingBy(User::getAge));
    printMap(map);
}

结果:

key=16, value=[User{age=16, name='16_1'}, User{age=16, name='16_2'}, User{age=16, name='16_3'}]
key=12, value=[User{age=12, name='12_1'}, User{age=12, name='12_2'}, User{age=12, name='12_3'}]
key=14, value=[User{age=14, name='14_1'}, User{age=14, name='14_2'}, User{age=14, name='14_3'}]

可以看到通过groupingBy只需一行代码就将list分组成map。groupingBy除了可以分组以外还可以利用Collectors类的其他方法进行统计或者也可以将value分组成其他集合类。

partitioningBy 分组

将user按照年龄分组

@Test
public void testPartitioningBy(){
    Map<Boolean, List<User>> map = list.stream()
            .collect(Collectors.partitioningBy(user -> user.getAge() >= 14));

    for (Map.Entry<Boolean, List<User>> entry : map.entrySet()) {
        Boolean key = entry.getKey();
        List<User> value = entry.getValue();
        System.out.println("key="+key+", value="+value);
    }
}

结果:

key=false, value=[User{age=12, name='12_1'}, User{age=12, name='12_2'}, User{age=12, name='12_3'}]
key=true, value=[User{age=16, name='16_1'}, User{age=16, name='16_2'}, User{age=16, name='16_3'}, User{age=14, name='14_1'}, User{age=14, name='14_2'}, User{age=14, name='14_3'}]

通过partitioningBy将list分成了两组,key是Boolean类型。所以partitioningBy的分组条件必须是一个Boolean类型的结果。

传统方式

传统方式就是自己去手动地实现分组逻辑。传统方式也是可以分为两种方式的。

  1. 手动创建Map对象
@Test
public void testMap(){
    Map<Integer, List<User>> map = new HashMap<>();
    for (User user : list) {
        Integer age = user.getAge();
        List<User> values = map.getOrDefault(age, new ArrayList<>());
        values.add(user);
        map.put(age, values);
    }
    printMap(map);
}

这种方式就是代码量相对大一点,但是同样也能实现分组的效果

  1. 手动创建一个MultiValueMap对象

这种方式跟上面那种手动方式差不多,但是更简单一点。

@Test
public void testMultiValueMap(){
    MultiValueMap<Integer, User> map = new LinkedMultiValueMap<>();
    for (User user : list) {
        Integer age = user.getAge();
        map.add(age, user);
    }
    printMap(map);
}

类似MultiValueMap的工具类应该也有很多,本文的MultiValueMap是org.springframework.util包下的一个工具类。MultiValueMap也是Map的实现类,但是限定了value必须是List集合。同时它又增加了自己的方法以实现value是List集合的形式。MultiValueMap实现类有好几个,要使用LinkedMultiValueMap才是我们要的list集合分组,添加value的时候用的是add方法而不是put方法。

总结

通过对比可以发现使用Lambda表达式的方式进行分组代码量更少一点,但是要求对Lambda表达式要熟悉。根据业务可以使用groupingBy分多组,也可以使用partitioningBy分两组。传统方式一眼就能让人看明白,可读性更好,使用传统方式的话优先还是选择MultiValueMap更为简单。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java list分组成map 的相关文章

随机推荐

  • react性能优化是哪个周期函数

    shouldComponentUpdate 这个方法用来判断是否需要调用render方法重新描绘dom 因为dom的描绘非常消耗性能 如果我们能在shouldComponentUpdate方法中能够写出更优化的dom diff算法 可以极大
  • 0基础如何学习软件测试?1小时给你安排明白

    先上一张学习路线 在测试行业已经呆了5年多了 也算得上行业经验资深了吧 基本上也是摸清了这个行业的发展 所以今天也想对有转行想法的朋友分享一下经验 能够让你对这个行业有个大致的了解和对以后的发展有所规划 不会像是个无头苍蝇一样毫无头绪 东打
  • 测试环境搭建

    测试环境的搭建 为什么搭建测试环境 如果开发人员调试代码和测试人员测试软件在同一环境内 则他们的工作会互相影响 因此 需要将待测软件系统单独部署在一个独立于开发环境的测试环境中 了解软件系统结构 B S 浏览器 服务器 概念 使用浏览器访问
  • mysql 数据备份与存储引擎

    数据备份 mysql home bin下提供了mysqldump exe mysqldump sh 的可执行文件 用于备份数据库 语法 无需进入MySQL命令行 在本机命令行即可 mysqldump h IP P port u账号 p da
  • 创建SSAS项目

    2 3 创建Analysis Services 设计好了结构良好的数据仓库 并且将需要分析的业务数据装载到了数据仓库中之后 就为满足商务决策的全方位需求打下了根基 以后的操作都是基于这些拥有数据的数据仓库进行的 但是 对数据的多维分析却并不
  • 中间件运维分析中的选型与实践

    在近期的 Kylin Data Summit 上 好买财富平台架构总监王晔倞在互联网专场上分享了好买财富在中间件运维分析平台的演进过程 好买财富为什么选择从广泛应用的 ELK 转向 Apache Kylin 呢 王晔倞 我们在监控上 通常会
  • 使用python做FamaMacBeth回归

    金融资产定价常常需要用到FamaMacBeth回归 我们用python写一个模板 可以直接将数据调成需要的格式 代入代码即可出结果 所要求的数据格式 可以从链接下载 https download csdn net download weix
  • 剑指 Offer 40. 最小的 k 个数

    系列文章目录 文章目录 系列文章目录 前言 一 剑指 Offer 40 最小的 k 个数 二 使用步骤 1 引入库 解法一 暴力破解法 冒泡排序 可惜超过时间限制 解法二 快速排序法 方法三 基于快速排序的数组划分 总结 前言 一 剑指 O
  • 前端埋点pv,uv以及实现思路

    埋点就是在应用或系统中通过特定的流程收集一些信息 用来跟踪项目或系统使用的状况 后续用来进一步优化产品或是提供运营的数据支撑 目前埋点实现方法可以分为三种类型 手动埋点 在需要统计数据的地方插入代码 需要入侵业务代码 优点是数据统计比较精准
  • 单片机毕设 基于单片机的人脸识别追踪

    文章目录 1 简介 2 项目简介 2 主要器件 3 硬件效果 4 软件设计 4 1 功能架构 4 2 软件程序流程图 5 部分实现代码 6 演示效果 6 最后 1 简介 Hi 大家好 今天向大家介绍一个学长做的单片机项目 基于单片机的人脸识
  • SQL Server的链接服务器创建全详细流程

    创建SQL Server链接服务器的详细流程如下 打开 SQL Server Management Studio SSMS 连接到你想要创建链接服务器的目标实例 在对象资源管理器中 展开 服务器对象 节点 右键点击 链接服务器 然后选择 新
  • 关联分析:Apriori算法

    本文代码及数据集来自 Python大数据分析与机器学习商业案例实战 步骤1 设定最小支持度和最小置信度 首先设定最小支持度为2 5 即40 最小置信度为4 5 即80 步骤2 根据最小支持度找出所有的频繁项集 这一步骤是关联分析中较为重要的
  • windows安装git和环境变量配置

    下载安装 1 从git官网下载一个git安装包 官网下载地址http www git scm com download 2 双击安装程序 进入欢迎界面点击 Next gt 3 阅读协议 点击 Next gt 4 选
  • modbus poll

    刚刚发布Modbus测试工具 Modbus Slave调试工具 不过已经是昨天了 今天开始发布Modbus测试工具 Modbus Master调试工具 做为Modbus主站 发送命令包 采集从站的数据 典型工具如 Modbus Poll M
  • 第十三章总结

    一 泛型 1 定义泛型类 泛型机制语法 类名
  • 用typedef来定义二维数组

    include
  • 线性表的基本操作,包括:创建、插入、删除、查找等基本操作

    标签 数据结构 线性表是数据结构中最直观 最简单的一类抽象数据类型 本次需要使用顺序表来实现线性表 并编写相应的测试程序对你所创建的顺序表及单链表进行测试 以下给出测试样例 输入数据格式 第一行只有一个整型数N 0
  • Linux详解

    一 Linux简介 Linux系统是一种自由和开放源代码的类Unix操作系统 只要遵循GNU通用公共许可证 任何人和机构都可以自由地使用Linux的所有底层源代码 也可以自由的修改和再发布 Linux这个词本身只表示Linux内核 但实际上
  • 1-Openwrt ipv6之-odhcp6c客户端

    wan口的拨号有好几种方式 SLAAC stateless DHCPv6 stateful DHCPv6 DHCPv6 PD 这些请求方式在odhcpv6里面都可以配置 1 odhcp6c客户端启动过程 开启openwrt config配置
  • java list分组成map

    文章目录 前期准备 实操 Lambda表达式方式 groupingBy分组 partitioningBy 分组 传统方式 总结 将List集合分成分组成map在工作中常常会遇到 这里我总结了两种方式 Lambda表达式方式和传统方式 前期准