首页 > 其他分享 >lambda 中 map 和 flatMap 的区别

lambda 中 map 和 flatMap 的区别

时间:2024-08-06 17:49:36浏览次数:8  
标签:map flatMap List Library Book new lambda

lambda 中 map 和 flatMap 的区别

 https://blog.csdn.net/weixin_52772307/article/details/128944511

 

总结:
当我们需要将具有层级结构的数据展平时,也就是将多层数据转换为单层数据操作时,我们可以使用 flatMap 方法。如果我们只是简单的对流中的数据计算或者转换时,可以使用 map 方法。

举例:
① 使用 flatMap:[a,b,c,d,[e,f [g,h,i]]] 转换为 [a,b,c,d,e,f,g,h,i]
② 使用 map: [1,2,3,4,5,6] 转换为 [11,12,13,14,15,16]
③ 使用 map: [a,b,c] 转换为 [A,B,C] 

 

 

 

一、map 和 flatMap 对应的源码
① map方法
<R> Stream<R> map(Function<? super T, ? extends R> mapper);

② flatMap方法
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
可以看到,不论是 map 还是 flatMap 方法,都是对以流的形式数据的处理,返回值同样都是流形式数据的泛型。本质一样,都是 map 操作,但是不同点在于,flatMap 操作会比 map 多一个 flat 操作。
"flat"单词本意有平的、扁平的含义,在源码中,我们对于 flatMap 方法中 API Note 有这样一句话:
"The flatMap() operation has the effect of applying a one-to-many transformation to the elements of the stream, and then flattening the resulting elements into a new stream.",
含义是:flatMap()操作的效果是对流的元素应用一对多转换,然后将生成的元素展平为新的流。
而map方法的返回是:返回由将给定函数应用于此流元素的结果组成的流。 说到这里可能还是会有些不太清晰,我们用代码演示一下。

 

 

二、代码演示
① 两个类,一个 Library 类,一个 Book 类

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Library {
   private String name;
   private List<Book> book;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Book {
   private String name;
   private String author;
   private Integer price;
}

 

② 测试类

public class StreamTest {
    public static void main(String[] args) {
        System.out.println("---------->存储的图书信息: ");
        System.out.println(initInfo());
        System.out.println("---------->测试map方法:");
        testMap();
        System.out.println("---------->测试flatMap方法:");
        testFlatMap();
    }
    private static void testMap() {
        initInfo().stream()
                .map(library -> library.getBook())
                .forEach(book -> System.out.println(book));
    }
 
    private static void testFlatMap() {
        initInfo().stream()
                .flatMap(library -> library.getBook().stream())
                .forEach(book -> System.out.println(book));
    }
 
    public static List<Library> initInfo() {
        Library library1 = new Library("新华图书", null);
        Library library2 = new Library("大家图书", null);
        Library library3 = new Library("瀚海图书", null);
 
        Book book1 = new Book("西游记", "吴承恩", 49);
        Book book2 = new Book("水浒传", "施耐庵", 57);
        Book book3 = new Book("三国演义", "罗贯中", 52);
        Book book4 = new Book("朝花夕拾", "鲁迅", 30);
 
        List<Book> library1Book = new ArrayList<>();
        List<Book> library2Book = new ArrayList<>();
        List<Book> library3Book = new ArrayList<>();
 
        library1Book.add(book1);
        library1Book.add(book2);
 
        library2Book.add(book2);
        library2Book.add(book3);
 
        library3Book.add(book3);
        library3Book.add(book4);
 
        library1.setBook(library1Book);
        library2.setBook(library2Book);
        library3.setBook(library3Book);
 
        return new ArrayList<>(Arrays.asList(library1, library2, library3));
    }
}

 

 
③ 测试结果

我们可以看到利用 flatMap 方法后,流中的数据被展平,消除了List<Book>的层级解构,但是 map 中的数据仍然存在层级结构。

map 方法流的中间过程 

 

flatMap 方法流的中间过程 

 可以清楚的看到,map 方法应用后是存在层级结构的,返回的流是List<Book>组成的流,而 flatMap 中消除了List<Book>的层级结构,返回的流是 Book 组成的流。 

 

总结:
当我们需要将具有层级结构的数据展平时,也就是将多层数据转换为单层数据操作时,我们可以使用 flatMap 方法。如果我们只是简单的对流中的数据计算或者转换时,可以使用 map 方法。

举例:
① 使用 flatMap:[a,b,c,d,[e,f [g,h,i]]] 转换为 [a,b,c,d,e,f,g,h,i]
② 使用 map: [1,2,3,4,5,6] 转换为 [11,12,13,14,15,16]
③ 使用 map: [a,b,c] 转换为 [A,B,C]

 

标签:map,flatMap,List,Library,Book,new,lambda
From: https://www.cnblogs.com/kelelipeng/p/18345731

相关文章

  • yolov5 mAP计算代码分析
    前言模型训练过程中每一轮都会计算P,R,mAP,[email protected]等数值,本篇分析这些数值的计算过程,分析最核心部分。我的感受是计算的过程比想象的复杂。主要的流程在yolov5/val.py文件的process_batch处理函数中。ifnl:tbox=xywh2xyxy(labels[:,1:5])#targetboxesscale_bo......
  • 【C++/STL】map和set的封装(红黑树)
     ......
  • Java集合:Collection and Map;ArrayList;LinkList;HashSet;TreeSet;HashMap;TreeMap;Iterator:
        集合介绍:                        是一组变量类型(容器),跟数组很像。一,引用集合的原因(必要性):                  A:数组的空间长度固定,一旦确定不可以更改。多了浪费,少了报错。          B:使用数......
  • MapperScannerConfigurer中获取applicayion.yml配置,进行动态加载BasePackage
     由于在MapperScannerConfigurer的bean优先于@value,导致@value取出来的时候都是null,所以只能使用Environment来获取值importorg.mybatis.spring.mapper.MapperScannerConfigurer;importorg.springframework.beans.factory.annotation.Value;importorg.springframework......
  • List,Set,Queue,Map接口
    List,Set,Queue,Map接口一.List接口List接口是Java集合框架中的一个重要接口,它继承自Collection接口。List接口表示一个有序的集合,其中的元素可以重复。这意味着在List中,每个元素都有一个特定的索引位置,我们可以通过这个索引来访问或操作元素。List接口的主要特点包括......
  • 记一次STM32使用I2C PinRemap引脚重映射出现卡死现象
    在移植WouoUI到STMF103C8BluePillboard时,发现会出现上电卡死在I2C检查函数(如下图)本人遇到的现象:在习惯使用的(SWI2C/HWI2C)@(PB8->SCLPB9->SDA)连接OLED的情况下,大多数情况使用江科大的SWI2C,一切正常。今天跑某开源基于u8g2库的UI框架WouoUI(HWI2C)@(PB6->SCLPB7->SDA)遇......
  • 【数据结构】Map和Set
    目录1.前言2.搜索树2.1概念2.2操作-查找2.3操作-插入2.4操作-删除2.5性能分析3.搜索3.1概念及场景3.2模型3.3Map的使用3.3.1关于Map的说明3.3.2关于Map.Entry的说明,>3.3.3Map的常用方法说明3.3.4TreeMap的使用3.4Set的使用3.4.1Set的说明3.4.2Set的常......
  • WPF WriteableBitmap通过GDI+绘制帮助类
    代码:publicclassWriteableBitmapGraphic:IDisposable{publicWriteableBitmapSource{get;privateset;}publicSystem.Drawing.Bitmapbitmap{get;privateset;}publicintDataLength{get;privateset;}publ......
  • 出现 No mapping for DELETE/GET等
    出现NomappingforDELETE/GET等错误一:请求url不对修改前如下图可知后端请求url为http://localhost:8080/user/addressBook运行后控制台出现发现后端请求url比前端请求url少了/改正:在@DeleteMapping后面加上/ @DeleteMapping("/")@ApiOperation("根据id......
  • 【转载】MapStruct使用填坑
    使用MapStruct的时候明明sourcefield不是null,转换完之后就变成null了,结果发现MapStruct生成的Converter是很久以前的,idea里面直接点运行并不会重新生成MapStruct的实现类,所以修改实体类之后一定要mvnclean。和这位仁兄碰到了一样的问题,心有戚戚焉,所以转载mapstruct是一个编译......