You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:57:22