什么叫只能执行映射?
我理解是把一个数据执行一个方法,转换成另外一个数据。举个例子:mapper 函数把输入的字符串转换成大写。map()方法执行这个 mapper 函数。
Function mapper = String::toUpperCase;
Flux inFlux = Flux.just("hello", ".", "com");
Flux outFlux = inFlux.map(mapper);
// reactor 测试包提供的测试方法
StepVerifier.create(outFlux)
.expectNext("HELLO", ".", "COM")
.expectComplete()
.verify();
什么叫展平?
mapper 函数把字符串转成大写,然后分割成一个一个字符。
Function> mapper = s -> Flux.just(s.toUpperCase().split(""));
Flux inFlux = Flux.just("hello", ".", "com");
// 这里只能使用 flatMap,因为参数是 Function> 形式
Flux outFlux = inFlux.flatMap(mapper);
List output = new ArrayList<>();
outFlux.subscribe(output::add);
// 输出 [H, E, L, L, O, ., C, O, M]
System.out.println(output);
请注意,由于来自不同来源的数据项交错,它们在输出中的顺序可能与我们在输入中看到的不同。
当流被订阅(subscribe)之后,映射器对输入流中的元素执行必要的转换(执行上述 mapper 操作)。这些元素中的每一个都可以转换为多个数据项,然后用于创建新的流。
一旦一个由 Publisher 实例表示的新流准备就绪,flatMap 就会急切地订阅。operator 不会等待发布者完成,会继续下一个流的处理,这意味着订阅是非阻塞的。同时也说明 flatMap() 是异步的。
由于管道同时处理所有派生流,因此它们的数据项可能随时进入。结果就是原有的顺序丢失。如果项目的顺序很重要,请考虑改用 flatMapSequential 运算符。
Function
,返回是 Flux
Function>
返回是 Flux
举例:
这里只能使用 flatMap,因为参数是 Function
形式
Function> mapper = s -> Flux.just(s.toUpperCase().split(""));
Flux inFlux = Flux.just("hello", ".", "com");
// 这里只能使用 flatMap,因为参数是 Function> 形式
Flux outFlux = inFlux.flatMap(mapper);
这里只能使用 map,因为参数是 Function
Function mapper = String::toUpperCase;
Flux inFlux = Flux.just("hello", ".", "com");
// 这里只能使用 map,因为参数是 Function
Flux outFlux = inFlux.map(mapper);
此外,看方法签名,可以看出,可以给 map() 传参 Function
,按照方法签名,它会返回Flux
,但它不知道如何处理 Publishers。比如下面的代码:编译不会报错,但是不知道后续怎么处理。
Function> mapper = s -> Flux.just(s.toUpperCase().split(""));
Flux inFlux = Flux.just("hello", ".", "com");
Flux> map = inFlux.map(mapper);
下面的例子来源于 stackoverflow:
使用 map 方法会产生 Mono
,而使用 flatMap 会产生 Mono
。使用 map() 就是给 map 传参了Function
,它返回的也是 Mono
。
// Signature of the HttpClient.get method
Mono get(String url);
// The two urls to call
String firstUserUrl = "my-api/first-user";
String userDetailsUrl = "my-api/users/details/"; // needs the id at the end
// Example with map
Mono> result = HttpClient.get(firstUserUrl).
map(user -> HttpClient.get(userDetailsUrl + user.getId()));
// This results with a Mono> because HttpClient.get(...)
// returns a Mono
// Same example with flatMap
Mono bestResult = HttpClient.get(firstUserUrl).
flatMap(user -> HttpClient.get(userDetailsUrl + user.getId()));
// Now the result has the type we expected
Flux stringFlux = Flux.just("hello word!");
Function> mapper = s -> Flux.just(s.toUpperCase().split(""));
// 使用 flatMap() 返回的是 FluxFlatMap.
Flux flatMapFlux = stringFlux.flatMap(mapper);
// 使用 map() 返回的是 FluxMapFuseable
Flux mapFlux = stringFlux.map(s -> s);
flatMapFlux 类型是 FluxFlatMap;也就是说,使用 flatMap() 返回的是 FluxFlatMap.
mapFlux 类型是 FluxMapFuseable。也就是说,使用 map() 返回的是 FluxMapFuseable
FluxMapFuseable 是什么?
FluxFlatMap 是什么?
FluxFlatMap 和 FluxMapFuseable 是什么区别?
各位看官可以一起讨论!
参考链接:
baeldung: Project Reactor: map() vs flatMap()
csdn: map VS flatmap
geeksforgeeks: Difference Between map() And flatMap() In Java Stream
stackOverFlow: map vs flatMap in reactor