2. flatMap、flatMapSequential、concatMap区别与联系

概述

      本文分享flatMap、flatMapSequential、concatMap之间的区别与联系。

flatMap

源码

public final <R> Flux<R> flatMap(Function<? super T, ? extends Publisher<? extends R>> mapper) {
   return flatMap(mapper, Queues.SMALL_BUFFER_SIZE, Queues
         .XS_BUFFER_SIZE);
}

jdk注释

Transform the elements emitted by this Flux asynchronously into 	Publishers, then flatten these inner publishers into a single Flux through merging, which allow them to interleave.
There are three dimensions to this operator that can be compared with flatMapSequential and concatMap:
Generation of inners and subscription: this operator is eagerly subscribing to its inners.
Ordering of the flattened values: this operator does not necessarily preserve original ordering, as inner element are flattened as they arrive.
Interleaving: this operator lets values from different inners interleave (similar to merging the inner sequences).

翻译

把Flux弹出的元素异步的转化成发布者(Publishers),然后把他们合并成一个Flux。在合并的过程中允许交错(不保证顺序)
可以从三个方面比较flatMap与flatMapSequential和concatMap的区别:
生成内部发布者与订阅关系:flatMap并发的订阅了它的内部发布者。
合并顺序:flatMap按照内部内部订阅到达顺序合并元素,它不保证与原始顺序一致。
交错:flatMap允许不同的内部订阅交错(与merge类似)

图示

在这里插入图片描述

flatMapSequential

源码

public final <R> Flux<R> flatMapSequential(Function<? super T, ? extends
      Publisher<? extends R>> mapper) {
   return flatMapSequential(mapper, Queues.SMALL_BUFFER_SIZE);
}

jdk注释

Transform the elements emitted by this Flux asynchronously into Publishers, then flatten these inner publishers into a single Flux, but merge them in the order of their source element.
There are three dimensions to this operator that can be compared with flatMap and concatMap:
Generation of inners and subscription: this operator is eagerly subscribing to its inners (like flatMap).
Ordering of the flattened values: this operator queues elements from late inners until all elements from earlier inners have been emitted, thus emitting inner sequences as a whole, in an order that matches their source's order.
Interleaving: this operator does not let values from different inners interleave (similar looking result to concatMap, but due to queueing of values that would have been interleaved otherwise).

翻译

把Flux弹出的元素异步的转化成发布者(Publishers),然后按照源头发出元素的顺序把他们合并成一个Flux。
可以从三个方面比较flatMapSequential与flatMap和concatMap的区别:
生成内部发布者与订阅关系:像flatMap一样,flatMapSequential并发的订阅了它的内部发布者。
合并顺序:flatMapSequential把所有的内部订阅排序,直到所有的订阅都完成,然后把所有的序列按照原始的顺序一起发出去。
交错:flatMapSequential不允许内部订阅相互交错(与concatMap的结果类似,flatMapSequential使用队列防止交错)

图示

在这里插入图片描述

concatMap

源码

public final <V> Flux<V> concatMap(Function<? super T, ? extends Publisher<? extends V>>
      mapper) {
   return concatMap(mapper, Queues.XS_BUFFER_SIZE);
}

jdk注释

Transform the elements emitted by this Flux asynchronously into Publishers, then flatten these inner publishers into a single Flux, sequentially and preserving order using concatenation.
There are three dimensions to this operator that can be compared with flatMap and flatMapSequential:
Generation of inners and subscription: this operator waits for one inner to complete before generating the next one and subscribing to it.
Ordering of the flattened values: this operator naturally preserves the same order as the source elements, concatenating the inners from each source element sequentially.
Interleaving: this operator does not let values from different inners interleave (concatenation).

翻译

把Flux弹出的元素异步的转化成发布者(Publishers),然后使用级联的方式,依照顺序依次把这些内部的publishers压平成一个Flux。
可以从三个方面比较concatMap与flatMap与flatMapSequential的区别:
生成内部发布者与订阅关系:concatMap等待一个内部订阅完成之后,在生成和订阅下一个。
压平顺序:concatMap保证拍平的顺序与源头发出元素的顺序一致,它依次把内部订阅级联起来。
交错:concatMap不允许内部订阅相互交错

图示

在这里插入图片描述

代码测试

public static void main(String[] args) throws Exception{

      List<Integer> list = new ArrayList<>();
      list.add(4);
      list.add(2);
      list.add(1);
      list.add(3);

      Flux.fromIterable(list).flatMap(item ->{
         return Mono.just(item).delayElement(Duration.ofMillis(item * 100));
      }).doOnSubscribe(subscribe ->{
         System.out.print("flatmap : ");
      }).doOnComplete(()->{
         System.out.println();
      }).subscribe(result ->{
         System.out.print(result + " ");
      });
      Thread.sleep(1100);

      Flux.fromIterable(list).flatMapSequential(item ->{
         return Mono.just(item).delayElement(Duration.ofMillis(item * 100));
      }).doOnSubscribe(subscription -> {
         System.out.print("flatMapSequential : ");
      }).doOnComplete(()->{
         System.out.println();
      }).subscribe(result ->{
         System.out.print(result + " ");
      });
      Thread.sleep(1100);

      Flux.fromIterable(list).concatMap(item ->{
         return Mono.just(item).delayElement(Duration.ofMillis(item * 100));
      }).doOnSubscribe(subscription -> {
         System.out.print("concatMap : ");
      }).doOnComplete(()->{
         System.out.println();
      }).subscribe(result ->{
         System.out.print(result + " ");
      });
      Thread.sleep(1100);
   }

      输出
在这里插入图片描述

总结

相同点

      1. 接口声明是一样的,都是把元素T转换成Publisher

不同点

      1. flatMap不保证顺序, flatMapSequential和concatMap保持顺序。
      2. flatMapSequential效率高,它是并发的,concatMap是串行方式。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值