首页
学习
活动
专区
工具
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());

参考链接

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

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

相关·内容

没有搜到相关的沙龙

领券