首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java stream: groupingBy和flatMapping密钥

基础概念

groupingByflatMap 是 Java 8 引入的 Stream API 中的两个重要操作。

  • groupingBy: 这是一个收集器(Collector),用于将流中的元素根据某个键进行分组。它返回一个 Map,其中键是分组的依据,值是分组后的元素集合。
  • flatMap: 这是一个流操作,用于将流中的每个元素转换为另一个流,并将这些流“扁平化”为一个单一的流。它主要用于处理嵌套的集合结构。

相关优势

  • groupingBy:
    • 便于数据分组和聚合操作。
    • 可以与多种收集器(如 counting, summingInt, averagingDouble 等)结合使用,进行复杂的数据分析。
  • flatMap:
    • 能够处理嵌套的集合结构,使代码更加简洁和易读。
    • 在处理多层嵌套数据时,可以显著减少代码量。

类型

  • groupingBy:
    • 可以接受一个函数作为参数,该函数用于提取每个元素的键。
    • 返回一个 Map<K, List<V>>,其中 K 是键的类型,V 是元素的类型。
  • flatMap:
    • 接受一个函数作为参数,该函数将每个元素转换为一个新的流。
    • 返回一个 Stream<R>,其中 R 是转换后流的元素类型。

应用场景

  • groupingBy:
    • 对用户按年龄分组,并统计每组的人数。
    • 对订单按产品类别分组,并计算每个类别的总销售额。
  • flatMap:
    • 将一个包含多个列表的列表扁平化为一个单一的列表。
    • 处理嵌套的 JSON 数据,将其转换为扁平的数据结构。

示例代码

groupingBy 示例

假设我们有一个 Person 类,包含姓名和年龄两个属性:

代码语言:txt
复制
public class Person {
    private String name;
    private int age;

    // 构造函数、getter 和 setter 省略
}

我们可以使用 groupingBy 对一组人按年龄进行分组:

代码语言:txt
复制
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class GroupingByExample {
    public static void main(String[] args) {
        List<Person> people = List.of(
            new Person("Alice", 25),
            new Person("Bob", 30),
            new Person("Charlie", 25)
        );

        Map<Integer, List<Person>> peopleByAge = people.stream()
            .collect(Collectors.groupingBy(Person::getAge));

        System.out.println(peopleByAge);
    }
}

flatMap 示例

假设我们有一个包含多个列表的列表,我们希望将其扁平化为一个单一的列表:

代码语言:txt
复制
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FlatMapExample {
    public static void main(String[] args) {
        List<List<Integer>> nestedLists = List.of(
            List.of(1, 2, 3),
            List.of(4, 5),
            List.of(6, 7, 8, 9)
        );

        List<Integer> flattenedList = nestedLists.stream()
            .flatMap(List::stream)
            .collect(Collectors.toList());

        System.out.println(flattenedList);
    }
}

常见问题及解决方法

问题:groupingBy 返回的 Map 中键的顺序不一致

原因groupingBy 默认使用 HashMap 作为底层实现,HashMap 不保证键的顺序。

解决方法:可以使用 LinkedHashMap 来保持键的插入顺序:

代码语言:txt
复制
Map<Integer, List<Person>> peopleByAge = people.stream()
    .collect(Collectors.groupingBy(Person::getAge, LinkedHashMap::new, Collectors.toList()));

问题:flatMap 处理嵌套流时出现空指针异常

原因:如果嵌套流中的某个元素为 null,调用 flatMap 时会抛出空指针异常。

解决方法:在使用 flatMap 之前,先过滤掉 null 值:

代码语言:txt
复制
List<List<Integer>> nestedLists = List.of(
    List.of(1, 2, 3),
    null,
    List.of(6, 7, 8, 9)
);

List<Integer> flattenedList = nestedLists.stream()
    .filter(list -> list != null) // 过滤掉 null 值
    .flatMap(List::stream)
    .collect(Collectors.toList());

参考链接

希望这些信息对你有所帮助!

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • Java8 Stream groupingBy对List进行分组

    其实Java8 Streams API中的Collector也支持流中的数据进行分组和分区操作,本片文章讲简单介绍一下,如何使用groupingBy 和 partitioningBy来对流中的元素进行分组和分区...groupingBy 首先看一下Java8之前如果想对一个List做分组操作,我们需要如下代码操作: @Test public void groupListBeforeJava8() { Map...中Stream的groupingBy分组器,就可以这样操作: /** * 使用java8 stream groupingBy操作,按城市分组list */ @Test public void groupingByTest...分组器最常见的一个用法,下面简单介绍一下其他用法: 统计每个分组的count /** * 使用java8 stream groupingBy操作,按城市分组list统计count */ @Test...示例代码:卓立 – 码云 – groupingBy操作 参考链接: Java 8 Streams API:对Stream分组和分区 Java 8 – Stream Collectors groupingBy

    3.9K20

    Java Stream API 操作完全攻略:让你的代码更加出色 (三)

    前言  Java Stream 是一种强大的数据处理工具,可以帮助开发人员快速高效地处理和转换数据流。使用 Stream 操作可以大大简化代码,使其更具可读性和可维护性,从而提高开发效率。...本文将为您介绍 Java Stream 操作的所有方面,包括 groupingBy、groupingBy、joining、mapping 等操作,让你的代码行云流水,更加优雅。...flatMapping():将每个元素映射为一个 Stream,然后将这些 Stream 连接成一个 Stream。...使用 groupingBy() 按照字符串长度对字符串列表进行分组代码示例:import java.util.Arrays;import java.util.List;import java.util.Map..., STREAM]复制代码5.使用 flatMapping() 将嵌套的字符串列表展平为一个字符串列表代码示例:import java.util.Arrays;import java.util.List

    32620

    Java数据分组:HashMap、Stream API的groupingBy、reduce实践

    在 Java 开发中,对大量数据进行高效分组和统计分析是常见任务。...本文探讨两种数据分组技术:HashMap 和 Java 8 的 groupingBy 与 reduce 方法,给出代码示例和应用场景分析1.使用HashMap实现数据分组HashMap是Java中最基础且广泛使用的键值对容器之一...使用Stream API中的groupingBy进行数据分组Java 8 Stream API提供了Collectors.groupingBy()方法,使得数据分组操作更为简洁和直观:import java.util...区别总结HashMap:手动控制分组,灵活性高,手动编码多,适用于简单分组和老 Java 项目。...Stream API groupingBy:内置分组机制,易理解维护,适用于大量数据和现代 Java 应用。Stream API reduce:可用于任何可归约场景,用于数据集汇总统计。

    10210

    Java 编程问题:九、函数式编程——深入研究

    本章包括 22 个涉及 Java 函数式编程的问题。这里,我们将重点讨论在流中遇到的涉及经典操作的几个问题(例如,filter和map),并讨论无限流、空安全流和缺省方法。...在流和函数式编程(java8)之前,这样的任务是通过一堆繁琐、冗长且容易出错的意大利面代码应用于集合的。从 Java8 开始,我们有分组收集器。 在下一节中,我们来看看单级分组和多级分组。...()和mapping(),特别是用于多级降阶(如groupingBy()或partitioningBy()的下游)。...是时候介绍flatMapping()了。通过使用flatMapping​(FunctionStreamstream() .collect(groupingBy(Melon::getType, flatMapping(m -> m.getPests().stream

    1.8K10

    Java Stream 解析和使用技巧

    stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java 容器或 I/O channel 等。 为函数式编程而生。...反过来从Stream生成Map是可以的,但我们要想清楚Map的key和value分别代表什么,根本原因是我们要想清楚要干什么。...使用Collectors.groupingBy()生成的收集器,对元素做group操作时用到。...Java 类库设计者也考虑到了这种情况,增强版的groupingBy()能够满足这种需求。增强版的groupingBy()允许我们对元素分组之后再执行某种运算,比如求和、计数、平均值、类型转换等。...终结函数返回 2) 检查 Optional 是否为空,一般和三元符配合使用,可同时照顾到非空和空 isPresent()?

    53220

    java 8 stream reduce详解和误区

    reduce详解 Stream类中有三种reduce,分别接受1个参数,2个参数,和3个参数,首先来看一个参数的情况: Optional reduce(BinaryOperator accumulator...接下来我们再看一下两个参数的例子: T reduce(T identity, BinaryOperator accumulator); 这个方法接收两个参数:identity和accumulator...并行计算和非并行计算的结果居然不一样,这肯定不是JDK的问题,我们再看一下JDK中对identity的说明: identity必须是accumulator函数的一个identity,也就是说必须满足:对于所有的...如果我们用0作为identity,则stream和parallelStream计算出的结果是一样的。这就是identity的真正意图。...super T, U> accumulator, BinaryOperator combiner); 和前面的方法不同的是,多了一个combiner,这个combiner

    92630

    java8 stream().map().collect()的Collectors.toList()、Collectors.toMap()、Collectors.groupingBy()的用法[通俗易

    ArrayList(); for(int i = 0; i < users.size(); i++){   idList.add(users.get(i).getId()); }   然而Java8...这里我也就只讲一个前两个用法,也就是2个参数的和3个参数的用法。   第一个参数,用于指定key的Function。   第二个参数,用于指定value的Function。   ...b));   (a, b) -> b的意思就是,如果存在重复的,永远取后面一个   这时,map里的值就是: { 18: "王五" 19: "李四" } 三、Collectors.groupingBy...当你想获取key是age的map,又不想覆盖掉重复项数据,这个时候就可以用 Collectors.groupingBy 了。...Map> map = userList.stream().collect(Collectors.groupingBy(User::getAge));   可以看到

    2.3K30

    java 中 parallelStream 和 stream 方法区别

    区别 Stream 和 parallelStream 都是用于处理集合数据的流式操作的方法。区别如下: 单线程 vs 并行处理: Stream 方法是单线程的,是按顺序逐个处理流中的元素。...Stream 方法在处理小规模数据或者需要保持顺序的情况下可能更适合,因为它没有并行处理的开销。 线程安全: Stream 方法是线程安全的,因为是单线程,没有多线程并发访问的问题。...parallelStream 方法在并行处理时存在线程安全性,因为多个线程可能同时访问和修改共享的数据。 结果顺序: Stream 方法保持元素的顺序,即使在并行处理时也会按照原始顺序输出结果。...总结 使用 Stream 方法适合处理小规模数据、需要保持顺序或对线程安全性要求较高的情况。 使用 parallelStream 方法适合处理大规模数据、不需要保持顺序或对性能要求较高的情况。

    56420
    领券