当前位置: 首页 > news >正文

mono map

// 使用 map(同步)

Mono<String> result1 = Mono.just("user1")

    .map(id -> id.toUpperCase()); // 同步操作

 

// 使用 flatMap(异步)

Mono<String> result2 = Mono.just("user1")

    .flatMap(id -> fetchUserAsync(id)); // fetchUserAsync 返回 Mono<String>

 

 

 

Mono.just("alice")

    .map(String::toUpperCase) // 同步: 转大写

    .flatMap(name -> saveToDatabase(name)) // 异步: 存数据库

    .subscribe(

        result -> System.out.println("Saved: " + result),

        error -> System.err.println("Error: " + error)

    );

 

 

// 错误示范(阻塞主线程)

Mono.just("data").map(s -> blockingCall(s));

 

// 正确做法

Mono.just("data")

    .flatMap(s -> Mono.fromCallable(() -> blockingCall(s))

                  .subscribeOn(Schedulers.boundedElastic()));

 

在 Project Reactor 中,`Mono` 的 `map` 方法是一个 **同步转换操作符**,用于对 `Mono` 中的元素进行一对一的转换。它的核心特点是 **非阻塞、同步执行**,适用于简单的数据转换场景。以下是详细说明和示例:

 

---

 

### **1. `map` 的核心特性**

- **同步执行**:转换操作(`Function`)会立即在当前线程执行,**不涉及异步操作**。

- **一对一转换**:输入一个值,输出一个转换后的值。

- **不改变 `Mono` 类型**:始终返回 `Mono<T>`,无法直接转换为 `Mono<R>` 以外的类型(如 `Flux`)。

 

---

 

### **2. 方法签名**

```java

Mono<R> map(Function<? super T, ? extends R> mapper)

```

- **输入**:`T` 类型的值(`Mono<T>` 中的元素)。

- **输出**:`R` 类型的转换结果(包装为 `Mono<R>`)。

 

---

 

### **3. 基础示例**

#### **示例 1:简单数据类型转换**

```java

Mono<Integer> numberMono = Mono.just(42);

Mono<String> stringMono = numberMono.map(num -> "The answer is " + num);

 

stringMono.subscribe(System.out::println); // 输出: The answer is 42

```

 

#### **示例 2:对象属性提取**

```java

record User(String name, int age) {}

 

Mono<User> userMono = Mono.just(new User("Alice", 30));

Mono<String> nameMono = userMono.map(User::name);

 

nameMono.subscribe(System.out::println); // 输出: Alice

```

 

---

 

### **4. 与 `flatMap` 的区别**

| 操作符 | 转换类型 | 是否支持异步 | 返回值 | 适用场景 |

|----------|---------------|--------------|-----------------|-----------------------|

| `map` | 同步 | ❌ 否 | `Mono<R>` | 简单计算、属性提取 |

| `flatMap`| 异步(嵌套) | ✅ 是 | `Mono<R>`/`Flux`| 调用返回 `Mono` 的服务 |

 

#### **对比代码**

```java

// 使用 map(同步)

Mono<String> result1 = Mono.just("user1")

    .map(id -> id.toUpperCase()); // 同步操作

 

// 使用 flatMap(异步)

Mono<String> result2 = Mono.just("user1")

    .flatMap(id -> fetchUserAsync(id)); // fetchUserAsync 返回 Mono<String>

```

 

---

 

### **5. 链式调用示例**

#### **场景:同步转换 + 异步操作组合**

```java

Mono.just("alice")

    .map(String::toUpperCase) // 同步: 转大写

    .flatMap(name -> saveToDatabase(name)) // 异步: 存数据库

    .subscribe(

        result -> System.out.println("Saved: " + result),

        error -> System.err.println("Error: " + error)

    );

```

 

---

 

### **6. 注意事项**

1. **不要阻塞 `map`**  

   如果转换逻辑涉及阻塞(如 IO、网络请求),必须改用 `flatMap` + `subscribeOn`:

   ```java

   // 错误示范(阻塞主线程)

   Mono.just("data").map(s -> blockingCall(s));

 

   // 正确做法

   Mono.just("data")

       .flatMap(s -> Mono.fromCallable(() -> blockingCall(s))

                     .subscribeOn(Schedulers.boundedElastic()));

   ```

 

2. **空 `Mono` 处理**  

   如果 `Mono` 为空(如 `Mono.empty()`),`map` 不会执行转换逻辑:

   ```java

   Mono.empty().map(Object::toString).subscribe(); // 无输出

   ```

 

3. **异常传播**  

   `map` 中的异常会直接终止流并触发 `onError`:

   ```java

   Mono.just("abc")

       .map(s -> { throw new RuntimeException("Oops"); })

       .subscribe(

           v -> {},

           e -> System.out.println("Error: " + e) // 触发

       );

   ```

 

---

 

### **7. 实际应用场景**

#### **场景 1:API 响应格式化**

```java

Mono<HttpResponse> apiResponse = fetchApi();

Mono<String> responseBody = apiResponse

    .map(HttpResponse::body)

    .map(body -> "Response: " + body);

```

 

#### **场景 2:数据预处理**

```java

Mono<RawData> rawDataMono = getRawData();

Mono<ProcessedData> processedMono = rawDataMono

    .map(data -> normalize(data))

    .map(data -> filterInvalid(data));

```

 

#### **场景 3:DTO 转换**

```java

Mono<UserEntity> entityMono = userRepository.findById(1);

Mono<UserDTO> dtoMono = entityMono.map(entity -> 

    new UserDTO(entity.getId(), entity.getName()));

```

 

---

 

### **总结**

- **`map`**:用于 **同步、非阻塞** 的简单转换。

- **`flatMap`**:用于 **异步** 操作(如调用返回 `Mono` 的服务)。

- **性能**:`map` 比 `flatMap` 更轻量,优先在同步场景使用。

 

通过合理选择 `map` 和 `flatMap`,可以高效构建响应式数据流。

 

相关文章:

  • 【验证技能】文档要求和好文档注意点
  • 无缝监控:利用 AWS X-Ray 增强 S3 跨账户复制的可见性
  • Java 中使用正则表达式
  • OkHttp3.X 工具类封装:链式调用,支持HTTPS、重试、文件上传【内含常用设计模式设计示例】
  • 初学Vue之记事本案例
  • 数字智慧方案6165丨智慧医养大数据平台(50页PPT)(文末有下载方式)
  • (34)VTK C++开发示例 ---将图片映射到平面
  • 初学者如何学习AI问答应用开发范式
  • go实现双向链表
  • 《排序算法总结》
  • Three.js在vue中的使用(一)-基础
  • 雅马哈SMT贴片机高效精密制造解析
  • kotlin中 热流 vs 冷流 的本质区别
  • 学习 Django 之前
  • 手撕哈希表
  • Elastic Search 的安装、使用方式
  • 【音视频】RTMP流媒体服务器搭建、推流拉流
  • AVDictionary 再分析
  • 原型模式(Prototype Pattern)详解
  • Redis持久化方式
  • “五一”假期国铁集团计划日均开行旅客列车超1.2万列
  • 美国防部监察机构扩大“群聊门”事件调查范围
  • 刘洪洁已任六安市委副书记、市政府党组书记
  • 长三角铁路今日预计发送旅客420万人次,有望创单日客发量新高
  • 200枚篆刻聚焦北京中轴线,“印记”申遗往事
  • 国台办:“台独”是绝路,外人靠不住