如何根据对象字段对列表进行分组并生成嵌套列表

发布时间 - 2026-01-31 00:00:00    点击率:

本文介绍如何基于 java 8 stream api 和 collectors.groupingby,按对象的指定字段(如 shape、size 或二者组合)将 list 动态分组为 list>,适用于多策略分组场景。

在实际开发中,常需根据业务类型(如 "type_1"、"type_2")对同一对象列表执行不同维度的分组逻辑:仅按 shape、仅按 size,或联合按 shape 和 size。核心目标是将原始 List 转换为 List> —— 即每个子列表包含字段值相同的对象。

✅ 基础分组:按单个字段(如 shape)

使用 Collectors.groupingBy(Obj::getShape) 可将对象按 shape 分组为 Map>,再提取其 values() 并转为 ArrayList 即可:

public List> groupByShape(List objs) {
    return new ArrayList<>(objs.stream()
        .collect(Collectors.groupingBy(Obj::getShape))
        .values());
}
⚠️ 注意:请确保 Obj 类已提供 getShape()(及 getSize())等标准 getter 方法;若字段为 private,直接访问 obj.shape 在 lambda 中不可行。

✅ 进阶分组:按多个字段(如 shape + size)

联合分组需构造唯一键。推荐使用 AbstractMap.SimpleEntry 或自定义键类,但最简洁安全的方式是用 Record(Java 14+)或匿名对象(Java 17+),或拼接字符串(需确保无歧义):

// 方式1:使用 record(推荐,类型安全、可读性高)
public List> groupByShapeAndSize(List objs) {
    return new ArrayList<>(objs.stream()
        .collect(Collectors.groupingBy(
            obj -> new AbstractMap.SimpleImmutableEntry<>(obj.getShape(), obj.getSize())
        ))
        .values());
}

// 方式2:字符串拼接(兼容低版本,但需注意转义,如 shape="a_b", size="c_d" 可能冲突)
public List> groupByShapeAndSizeSafe(List objs) {
    return new ArrayList<>(objs.stream()
        .collect(Collectors.groupingBy(
            obj -> obj.getShape() + "\0" + obj.getSize() // 使用不可见分隔符 \0 更安全
        

)) .values()); }

✅ 统一调度:在 functionName 中集成策略

将分组逻辑封装为函数式接口,使主流程清晰可维护:

public void functionName(Map> objMap) {
    Map, List>>> strategies = Map.of(
        "type_1", this::groupByShape,
        "type_2", this::groupBySize,
        "type_3", this::groupByShapeAndSize
    );

    objMap.forEach((type, objs) -> {
        Function, List>> strategy = strategies.get(type);
        if (strategy != null) {
            List> grouped = strategy.apply(objs);
            // ✅ 此处执行后续处理:如统计、聚合、持久化等
            processGroupedResults(grouped);
        }
    });
}

private void processGroupedResults(List> grouped) {
    for (int i = 0; i < grouped.size(); i++) {
        System.out.println("Group " + (i + 1) + ": " + grouped.get(i).size() + " objects");
        // e.g., grouped.get(i) is a List with same shape/size
    }
}

? 验证示例输出

以输入:

{
  "key": "type_3",
  "value": [
    {"size":"m1","shape":"s1","name":"Obj_1"},
    {"size":"m2","shape":"s1","name":"Obj_2"},
    {"size":"m1","shape":"s1","name":"Obj_3"}
  ]
}

调用 groupByShapeAndSize() 后,将生成:

  • [(s1,m1) → [Obj_1, Obj_3]]
  • [(s1,m2) → [Obj_2]]
    → 最终 List> 包含两个子列表,完全符合预期。

✅ 总结

  • 使用 Collectors.groupingBy 是实现动态分组的最简高效方案;
  • 单字段分组直接传方法引用(如 Obj::getShape);
  • 多字段分组优先使用 SimpleImmutableEntry 或 record 构建复合键,避免字符串拼接风险;
  • 将分组策略与主逻辑解耦(如 Map),提升可扩展性与可测试性;
  • 所有分组结果均为内存内 List>,无需额外依赖,开箱即用。


# java  # js  # app  # stream  # String  # 封装  # 字符串  # Lambda  # 接口  # private  # map  # function  # 对象  # 多字  # 进阶  # 多个  # 推荐使用  # 均为  # 适用于  # 自定义  # 可将  # 转换为  # 中不 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】  音响网站制作视频教程,隆霸音响官方网站?  高性价比服务器租赁——企业级配置与24小时运维服务  什么是JavaScript解构赋值_解构赋值有哪些实用技巧  车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?  作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】  Laravel如何处理异常和错误?(Handler示例)  Claude怎样写约束型提示词_Claude约束提示词写法【教程】  C++时间戳转换成日期时间的步骤和示例代码  javascript如何操作浏览器历史记录_怎样实现无刷新导航  深圳网站制作培训,深圳哪些招聘网站比较好?  Bootstrap CSS布局之列表  在Oracle关闭情况下如何修改spfile的参数  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  利用python获取某年中每个月的第一天和最后一天  php做exe能调用系统命令吗_执行cmd指令实现方式【详解】  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  如何有效防御Web建站篡改攻击?  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  如何快速打造个性化非模板自助建站?  香港服务器租用费用高吗?如何避免常见误区?  Edge浏览器怎么启用睡眠标签页_节省电脑内存占用优化技巧  Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】  大连 网站制作,大连天途有线官网?  Laravel怎么在Controller之外的地方验证数据  Python面向对象测试方法_mock解析【教程】  Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践  浅述节点的创建及常见功能的实现  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  C语言设计一个闪闪的圣诞树  5种Android数据存储方式汇总  原生JS实现图片轮播切换效果  Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】  佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】  Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中  如何快速生成ASP一键建站模板并优化安全性?  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  网站建设保证美观性,需要考虑的几点问题!  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  java获取注册ip实例  Android滚轮选择时间控件使用详解  Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道  如何快速辨别茅台真假?关键步骤解析  打造顶配客厅影院,这份100寸电视推荐名单请查收  南京网站制作费用,南京远驱官方网站?  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解