You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将List<Person>转换为Map<String, Map<LocalDate,List<Person>>>?

用Java 8 Stream API实现双层分组

这问题太常见了!刚好可以用Java 8引入的Stream API结合Collectors.groupingBy来完成双层分组,代码简洁又高效。

核心实现代码

直接上最简洁的解决方案,一行流操作就能搞定:

// 假设你已经有了Person集合
List<Person> personList = getYourPersonList();

Map<String, Map<LocalDate, List<Person>>> groupedMap = personList.stream()
    // 第一层按personId分组,第二层按date分组
    .collect(Collectors.groupingBy(
        Person::getPersonId,  // 外层Map的键:personId
        Collectors.groupingBy(Person::getDate)  // 内层Map的键:date,值是对应日期的Person列表
    ));

代码解释

  • 第一个Collectors.groupingBy(Person::getPersonId):先把整个List按personId拆分,得到一个Map<String, List<Person>>,每个键是唯一的personId,对应的值是该id下所有Person对象的集合。
  • 第二个groupingBy作为下游收集器,把每个personId分组里的List再按date做二次分组,最终就得到了你需要的Map<String, Map<LocalDate, List<Person>>>结构。

进阶:处理空值与自定义排序

如果你的业务场景中存在personId或date为null的情况,建议先过滤掉这些无效数据,避免空指针异常:

Map<String, Map<LocalDate, List<Person>>> groupedMap = personList.stream()
    // 过滤掉personId或date为空的对象
    .filter(p -> p.getPersonId() != null && p.getDate() != null)
    .collect(Collectors.groupingBy(
        Person::getPersonId,
        Collectors.groupingBy(Person::getDate)
    ));

要是还想对每个日期分组里的Person列表做排序(比如按type字段排序),可以在第二层分组里再加一个收集器:

Map<String, Map<LocalDate, List<Person>>> groupedMap = personList.stream()
    .collect(Collectors.groupingBy(
        Person::getPersonId,
        Collectors.groupingBy(
            Person::getDate,
            // 先收集成List,再按type排序
            Collectors.collectingAndThen(
                Collectors.toList(),
                list -> list.stream().sorted(Comparator.comparing(Person::getType)).collect(Collectors.toList())
            )
        )
    ));

内容的提问来源于stack exchange,提问作者Ram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:49:57