Java Lambda 分片(分组 / 分区)超详细讲解

在 Java 中,Lambda 结合 Stream API 实现的分片 ,本质就是把一个集合 / 流,按照指定规则拆分成多个小集合,最核心的两个 API 是:

  • Collectors.groupingBy()分组(按任意条件分成 N 组,key = 分组条件,value = 对应元素列表)
  • Collectors.partitioningBy()分区(特殊分组,只能分成 true/false 两组)

日常说的「分片」,90% 指 groupingBy 分组,10% 指 partitioningBy 分区,我会用最通俗的语言 + 实战代码讲透。


一、先搞懂:什么是 Lambda 分片?

给你一个集合,比如 List<Student>,你想:

  1. 年龄 分成:18 岁一组、19 岁一组、20 岁一组 → groupingBy 分组
  2. 是否成年 分成:成年一组、未成年一组 → partitioningBy 分区

这就是 Lambda 分片一行代码,用流式 + Lambda 表达式,快速拆分集合,不用写循环、if-else。


二、核心 API 1:Collectors.groupingBy () 【最常用:分组分片】

1. 作用

按照 自定义的分类规则(Lambda 函数) ,把流分成 多个组 ,返回 Map<分类结果, List<原元素>>

2. 3 种常用用法(必掌握)

(1)基础分组:单条件分片
java 复制代码
// 实体类
@Data
@AllArgsConstructor
class Student {
    private String name;
    private int age;
    private String gender;
}

// 测试数据
List<Student> list = Arrays.asList(
    new Student("张三", 18, "男"),
    new Student("李四", 19, "男"),
    new Student("王五", 18, "女"),
    new Student("赵六", 19, "女")
);

// ====================== Lambda 分组分片 ======================
// 按年龄分组(key=年龄,value=对应学生列表)
Map<Integer, List<Student>> groupByAge = list.stream()
    .collect(Collectors.groupingBy(Student::getAge)); // Lambda 简写

// 等价 Lambda 完整写法
// .collect(Collectors.groupingBy(s -> s.getAge()));

结果

  • key=18 → 张三,王五
  • key=19 → 李四,赵六

(2)多级分组:嵌套分片(先按性别,再按年龄)
java 复制代码
// 先按性别分,再按年龄分 → 双层 Map
Map<String, Map<Integer, List<Student>>> multiGroup = list.stream()
    .collect(Collectors.groupingBy(
        Student::getGender,       // 第一层分组:性别
        Collectors.groupingBy(Student::getAge) // 第二层分组:年龄
    ));

结果

  • 男 → {18=张三, 19=李四}
  • 女 → {18=王五, 19=赵六}

(3)分组 + 聚合:分片后统计(数量、总和、平均值)

分片后不只想要列表,还想要每组数量、总和、平均值

java 复制代码
// 按性别分组,统计每组人数
Map<String, Long> groupCount = list.stream()
    .collect(Collectors.groupingBy(
        Student::getGender,
        Collectors.counting() // 聚合:计数
    ));

// 按性别分组,统计平均年龄
Map<String, Double> groupAvgAge = list.stream()
    .collect(Collectors.groupingBy(
        Student::getGender,
        Collectors.averagingInt(Student::getAge) // 聚合:平均值
    ));

三、核心 API 2:Collectors.partitioningBy () 【分区:二分片】

1. 作用

只能分成两组true 一组、false 一组,返回 Map<Boolean, List<原元素>>

适用场景:只有两种结果的分片(是 / 否、通过 / 不通过、成年 / 未成年)。

2. 实战代码

java 复制代码
// 按【是否成年】分片(true=成年,false=未成年)
Map<Boolean, List<Student>> partition = list.stream()
    .collect(Collectors.partitioningBy(s -> s.getAge() >= 18));

// 获取成年学生
List<Student> adults = partition.get(true);
// 获取未成年学生
List<Student> minors = partition.get(false);

3. 特点

  • 永远返回 两个 keytruefalse(哪怕对应列表为空)
  • 条件必须是 返回 boolean 的 Lambda

四、groupingBy 和 partitioningBy 对比(一看就懂)

表格

特性 groupingBy (分组) partitioningBy (分区)
分片结果 任意 N 组 固定 2 组(true/false)
返回类型 Map<K, List<T>> Map<Boolean, List<T>>
Lambda 返回值 任意类型(对象、数值等) 必须 boolean
空分组 不会生成空 key 一定有 true/false 两个 key
适用场景 多条件分类、复杂分片 二分类、是非判断

五、Lambda 分片的完整实战示例(可直接运行)

java 复制代码
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class LambdaSplitDemo {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
            new Student("小明", 17, "男"),
            new Student("小红", 18, "女"),
            new Student("小刚", 19, "男"),
            new Student("小丽", 18, "女")
        );

        // 1. 分组分片:按年龄
        Map<Integer, List<Student>> groupByAge = students.stream()
                .collect(Collectors.groupingBy(Student::getAge));
        System.out.println("按年龄分组:" + groupByAge);

        // 2. 分区分片:是否成年
        Map<Boolean, List<Student>> partitionByAdult = students.stream()
                .collect(Collectors.partitioningBy(s -> s.getAge() >= 18));
        System.out.println("是否成年分区:" + partitionByAdult);

        // 3. 分组+统计:按性别统计人数
        Map<String, Long> groupCount = students.stream()
                .collect(Collectors.groupingBy(Student::getGender, Collectors.counting()));
        System.out.println("按性别统计人数:" + groupCount);
    }
}

@Data
@AllArgsConstructor
class Student {
    private String name;
    private int age;
    private String gender;
}

关键记忆点(背会就能写代码)

1. 一句话区分两个分片 API

  • 多结果分片 → 用 groupingBy(Lambda 返回任意值)
  • 二结果分片 → 用 partitioningBy(Lambda 必须返回 boolean)

2. 核心语法模板(直接套用)

java 复制代码
// 分组分片
Map<结果类型, List<元素>> 变量 = 集合.stream()
    .collect(Collectors.groupingBy( Lambda 分组条件 ));

// 分区分片
Map<Boolean, List<元素>> 变量 = 集合.stream()
    .collect(Collectors.partitioningBy( Lambda 布尔条件 ));

3. 必背 3 个分组聚合用法

  • Collectors.counting():统计每组数量
  • Collectors.summingInt():统计每组数值和
  • Collectors.averagingInt():统计每组平均值

4. 核心特性

  1. 分片是 Stream 终止操作 ,必须用 collect() 接收
  2. 分组返回 Map,key 是分组条件结果,value 是元素列表
  3. 分区永远有 true/false 两个 key,分组没有空 key
  4. Lambda 写法:对象::get方法 等价 s -> s.getXXX()

总结

  1. Java Lambda 分片 = Stream + Collectors 分组 / 分区,替代繁琐循环
  2. groupingBy:通用多组分片,工作中最常用
  3. partitioningBy:专用二分片,简单场景使用
  4. 记忆核心:多组用 groupingBy,二组用 partitioningBy
相关推荐
qq_369224337 天前
Windows全系通用!ntdll.dll文件丢失、报错、闪退问题的完整排查与修复教程
windows·dll·dll修复·dll丢失·dll错误
阿米亚波7 天前
【Windows】QEMU 启动 openEuler aarch64/arm64 架构系统 + 离线软件源
linux·windows·经验分享·笔记·架构·arm
caimouse7 天前
Reactos 第 10 章 网络操作 — 10.3.1 NIC驱动
网络·windows
初圣魔门首席弟子7 天前
Node.js 详细介绍(知识库版)
windows·qt·node.js·知识库
CHENG-JustDoIt7 天前
AI工具 | 爆火开源项目Odysseus AI 工作台:从项目介绍、部署情况及其使用等多方位分析指南(含详细步骤)
大数据·人工智能·windows·python·ai·开源·github
kingbal7 天前
Windows:flutter环境搭建
windows·flutter
未若君雅裁7 天前
Python 数据容器详解,list、tuple、str、set、dict 到底怎么选
windows·python·list
CodeKwang7 天前
Windows 环境 OCCT 8.0 编译构建及与 Qt6 项目集成
windows·qt·opencascade
我是伪码农7 天前
小兔鲜1-25
linux·服务器·windows
vx-Biye_Design7 天前
springboot安阳地区研学旅游服务小程序-计算机毕业设计源码12785
java·vue.js·windows·spring boot·tomcat·maven·mybatis