开发者

Java中的stream流分组示例详解

目录
  • 什么是stream流
  • 1、根据某个字段分组
  • 2、按多个字段分组(组合分组)
    • 1、方法一:使用 String 拼接作为分组 key(简单但不够灵活)
    • 2、使用 Map.Entry(Java 8+ 就支持):
    • 3、使用 record(Java 16+):
  • 3、分组后获取其他统计信息
    • 1、分组后统计每组的数量
    • 2、分组后获取每组中的某个属性集合,比如所有部门下的用户名
    • 3、分组后求每组的某个属性的最大值 / 最小值 / 平均值
  • 4、自定义分组key

    什么是stream流

    Java 8引入的Stream API是处理集合数据的一种全新方式,它代表了对数据元素序列进行函数式操作的抽象。Stream不是数据结构,而是一种高级的数据处理工具,允许你以声明式的方式处理数据集合,类似于SQL语句操作数据库。

    Stream的核心特点:

    • 声明式编程:只需说明"做什么"而非"如何做",代码更简洁易读
    • 函数式风格:与Lambda表达式完美结合,操作更灵活
    • 管道操作:多个操作可以连接起来形成数据处理流水线
    • 内部迭代:不同于集合的外部迭代(使用for-each),Stream在内部处理迭代过程
    • 延迟执行:中间操作不会立即执行,只有遇到终结操作才会触发计算
    • 不可复用:一个Stream只能被消费一次

    1、根据某个字段分组

     // 按 department 字段分组
            Map<String, List<User>> groupedByDept = users.stream()
                .collect(Collectors.groupingBy(User::getDepartment));

    2、按多个字段分组(组合分组)

    1、方法一:使用 String 拼接作为分组 key(简单但不够灵活)

    Map<String, List<User>> grouped = users.stream()
        .collect(Collectors.groupingBy(
            user -> user.getDepartment() + "-" + user.getJobTitle()
        ));

    2、使用 Map.Enjavascripttry(Java 8+ 就支持):

    Map<Map.Entry<String, String&编程客栈gt;, List<User>> grouped = users.stream()
        .collect(Collectors.groupingBy(
            user -> Map.entry(user.getDepartment(), user.getJobTitle())
        ));

            这样 key 是一个 Map.Entry<部门, 职位>,可以唯一确定一个组合

    3、使用 record(Java 16+):

    // 定义一个记录类作为分组 key
    record DeptJobKey(String department, String jobTitle) {}
    Map<DeptJobKey, List<User>> grouped = users.stream()
        .collect(Collectors.groupingBy(
            user -> new DeptJobKey(user.getDepartment(), user.getJobTitle())
        ));

    3、分组后获取其他统计信息

    1、分组后统计每组的数量

    Map<String, Long> countByDept = users.stream()
        .collect(Collectors.groupingBy(
            User::getDepartment,
            Collectors.counting()  // 统计每个部门的用户数
        ));
    

    2、分组后获取每组中的某个属性集合,比如所有部门下的用户名

    Map<String, List<String>> namesByDept = users.stream()
        .collect(Collectors.groupingBy(
            User::getDepartment,
            Collectors.mapping(User::getName, Collectors.toList()) // 只提取 name 字段
        ));
    

    3、分组后求每组的某个属性的最大值 / 最小值 / 平均值

    Map<String, Optional<Integer>> maxAgeByDept = users.stream()
        .collect(Collectors.groupingBy(
            User::getDepartment,
            Collectors.mapping(User::getAge, Collectors.maxBy(Comparator.naturalOrder()))
        ));
    // 或者更直观地使用 Collectors.maxBy / averagingInt 等
    //或者使用 Collectors.summarizingInt 做综合统计
    Map<String, IntSummaryStatistics> ageStatsByDept = users.stream()
        .collect(Collectors.groupingBy(
            User::getDepartment,
            Collectors.summarizingInt(User::getAge)  // 统计年龄:counpythont, sum, min, 编程客栈max, avg
        ));

    4、自定义分组key

    Map<String, List<User>> collect = javaList.stream().collect(Collectors.groupingBy(user -> {
                String id = user.getId();
                return (StringUtils.isEmpty(id)) ? "empty" : "notEmpty"; // 如果为 null,返回empty,不为空notEmpty
       android     }));

    到此这篇关于Java的stream流分组的文章就介绍到这了,更多相关Java stream流分组内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜