• Stream流中的Map与flatMap的区别


    0. 先说结论

    1. map的作用:是将输入一种类型,转化为另一种类型,通俗来说:就是将输入类型变成另一个类型。
    2. flatMap的作用:是扁平化的,比如有对象List> userLists, 这属于套娃现象,而最终我们只想得到List userList对象,即将多维集合,变成一个集合,相当于压缩,俗称扁平化。

    1. 需求

    1. 之前在做开发的时候,遇到如下需求:
      List对象,需要获取到List peopleNameList对象

      // 解释:一个房间有自己的房间号,里面有一堆人,每个人都有面子
      	@Data
          @AllArgsConstructor
          @NoArgsConstructor
          static class Room {
              private int number;
              private List<People> peopleList;
      
      
              @Data
              @NoArgsConstructor
              @AllArgsConstructor
              static class People {
                  private String name;
              }
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

    2. 解决方案

    1. 使用Map方法

    1. 如下:如果只是使用普通的map方法且里面是直接getPeopleList()方法,则得到的是 List> collect 对象。

      public class demo {
          public static void main(String[] args) {
              final List<Room> roomList = initRoom();
              List<List<Room.People>> collect = roomList.stream()
                      .map(Room::getPeopleList)
                      .collect(Collectors.toList());
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    2. 通常遇到这情况,一般人解决就是在遍历一次,如下:

      public class demo {
          public static void main(String[] args) {
              final List<Room> roomList = initRoom();
              List<List<Room.People>> collect = roomList.stream()
                      .map(Room::getPeopleList)
                      .collect(Collectors.toList());
              // 1.先new ArrayList<>() 准备存储String字符串
              List<String> peopleNameList = new ArrayList<>();
              // 2. 这里就得套两层的foreach了
              // 因为初始化是List>对象
              // 第一次foreach中peopleList 是List对象
              collect.forEach(peopleList -> {
               	// 第二次foreach中people 是People对象
                  peopleList.forEach(people -> {
                      peopleNameList.add(people.getName());
                  });
              });
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    3. 而有的人可能会在上面的基础上,再进一步优化为如下:

      public class demo {
          public static void main(String[] args) {
              final List<Room> roomList = initRoom();
      
              List<String> peopleNameList = new ArrayList<>();
      		// 直接一直使用stream流的foreach
      		// 虽然是比上面代码优雅多了,但两个foreach,怎么看都不舒服
              roomList.stream().forEach(room -> {
                  room.getPeopleList().forEach(people -> {
                      peopleNameList.add(people.getName());
                  });
              });
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

    2. 使用flatMap解决

    1. flatMap就是用于多层结构的扁平化,如下:

      public class demo {
          public static void main(String[] args) {
              final List<Room> roomList = initRoom();
      
              List<String> peopleNameList = roomList.stream()
                      .map(Room::getPeopleList)
                      .flatMap(Collection::stream)
                      .map(Room.People::getName)
                      .collect(Collectors.toList());
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      在这里插入图片描述

    3. 完整代码

    1. 代码如下:

      public class demo {
              public static void main(String[] args) {
                  final List<Room> roomList = initRoom();
      
                  // Map方法
                  List<String> peopleNameList = new ArrayList<>();
                  
                  roomList.stream().forEach(room -> {
                      room.getPeopleList().forEach(people -> {
                          peopleNameList.add(people.getName());
                      });
                  });
                  
                  // flatMap 方法
                  List<String> peopleNameList2 = roomList.stream()
                          .map(Room::getPeopleList)
                          .flatMap(Collection::stream)
                          .map(Room.People::getName)
                          .collect(Collectors.toList());
              }
      
          // 初始化10条数据
          private static List<Room> initRoom() {
              return IntStream.range(1, 11)
                      .mapToObj(num -> new Room(num, Arrays.asList(new Room.People("name:" + num), new Room.People("name:" + 10 * num))))
                      .collect(Collectors.toList());
          }
      
          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          static class Room {
              private int number;
              private List<People> peopleList;
      
      
              @Data
              @NoArgsConstructor
              @AllArgsConstructor
              static class People {
                  private String name;
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
  • 相关阅读:
    【Spring源码】9. 重要的ConfigurationClassPostProcessor
    【Vue3】使用mitt实现任意组件通信
    2-1 C++类的转换函数与禁止隐士转换(explicit)
    Spring注解RequestBody与RequestParam详解
    论企业私域流量运营中的玩法创新与开源 AI 智能名片 O2O 商城小程序的应用
    用上这个建筑管理技巧,我才知道有多省事!
    Java并发编程系列32:线程池shutdown()和exs.isTerminated()结合使用
    算法学习 | 深度优先搜索~一条道走到黑
    SQL*PLUS对文本长度的限制
    Kafka快速入门
  • 原文地址:https://blog.csdn.net/xueyijin/article/details/125901455