如何在单个Mono为空时合并两个Mono并创建Employee对象
处理Mono为空时构建Employee对象的需求
我有两个Mono<String>类型的对象firstName和lastName,其中任意一个都可能为空(即返回Mono.empty())。需要实现:
- 只要其中一个Mono有值,就创建对应字段填充的Employee对象
- 当两个Mono都为空时,创建一个空的Employee对象
当前方案的缺陷
之前尝试的两种写法,仅能在两个Mono同时不为空时成功构建Employee;只要其中一个为空,整个Mono就会返回空,无法满足需求:
第一种:使用Mono.zip的写法
public class Main { public static void main(String[] args) { Mono<String> firstName = Mono.just("Pavan"); Mono<String> lastName = Mono.empty(); Mono<Employee> map = Mono.zip(firstName, lastName) .flatMap(t -> Mono.just(Employee.builder() .firstName(t.getT1()) .lastName(t.getT2()) .build())); System.out.println(map.block()); } @Builder @ToString public static class Employee { private String firstName; private String lastName; } }
第二种:嵌套flatMap+map的写法
Mono<Employee> employeeMono = firstName .flatMap(first -> lastName.map(last -> Employee.builder() .firstName(first) .lastName(last) .build()));
正确解决方案
核心思路是为每个可能为空的Mono设置默认值(比如null),确保组合操作总能拿到有效值,进而构建Employee对象。
方法一:defaultIfEmpty + Mono.zip
public class Main { public static void main(String[] args) { Mono<String> firstName = Mono.just("Pavan"); Mono<String> lastName = Mono.empty(); // 为空的Mono返回null作为默认值 Mono<String> safeFirstName = firstName.defaultIfEmpty(null); Mono<String> safeLastName = lastName.defaultIfEmpty(null); Mono<Employee> employeeMono = Mono.zip(safeFirstName, safeLastName) .map(tuple -> Employee.builder() .firstName(tuple.getT1()) .lastName(tuple.getT2()) .build()); System.out.println(employeeMono.block()); // 输出:Employee(firstName=Pavan, lastName=null) } @Builder @ToString public static class Employee { private String firstName; private String lastName; } }
也可以简化为链式调用:
Mono<Employee> employeeMono = Mono.zip( firstName.defaultIfEmpty(null), lastName.defaultIfEmpty(null) ).map(tuple -> Employee.builder() .firstName(tuple.getT1()) .lastName(tuple.getT2()) .build());
方法二:Mono.combineLatest
和上面效果一致,写法更紧凑:
Mono<Employee> employeeMono = Mono.combineLatest( firstName.defaultIfEmpty(null), lastName.defaultIfEmpty(null), (first, last) -> Employee.builder() .firstName(first) .lastName(last) .build() );
原方案失效原因
Mono.zip要求所有传入的Mono都必须发出元素,若有一个是Mono.empty(),整个zip操作直接返回Mono.empty(),不会进入后续处理逻辑- 嵌套
flatMap写法中:若firstName为空,flatMap不会执行;若firstName有值但lastName为空,lastName.map(...)返回empty(),最终整个employeeMono也为空
内容的提问来源于stack exchange,提问作者nanpakal
相关产品推荐
相关产品推荐

