Project Reactor 是一个用于实现响应式编程的库,它提供了两个核心类型:Flux 和 Mono。本文将重点介绍 Flux,介绍创建 Flux 的不同方法以及它们的区别,并通过代码示例演示 Flux 的常见用法。
创建 Flux 的方法
- Flux.just():使用提供的元素创建一个包含静态值的 Flux。
Flux<String> flux = Flux.just("Apple", "Banana", "Cherry");
- Flux.fromIterable():从一个
Iterable(如 List 或 Set)创建一个 Flux。
List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry");
Flux<String> flux = Flux.fromIterable(fruits);
- Flux.fromArray():从一个数组创建一个 Flux。
String[] fruits = {"Apple", "Banana", "Cherry"};
Flux<String> flux = Flux.fromArray(fruits);
- Flux.fromStream():从一个 Java Stream 创建一个 Flux。
Stream<String> fruitStream = Stream.of("Apple", "Banana", "Cherry");
Flux<String> flux = Flux.fromStream(fruitStream);
- Flux.range():创建一个包含范围内整数的 Flux。
Flux<Integer> flux = Flux.range(1, 5); // 生成 1, 2, 3, 4, 5
- Flux.interval():创建一个包含固定时间间隔发出的递增序列的 Flux。
Flux<Long> flux = Flux.interval(Duration.ofSeconds(1)); // 每秒发出递增的整数
- Flux.empty():创建一个不包含任何元素的 Flux。
Flux<String> flux = Flux.empty();
- Flux.error():创建一个发出错误的 Flux。
Flux<String> flux = Flux.error(new RuntimeException("An error occurred"));
- Flux.create():使用
FluxSink对象动态生成元素的 Flux。
Flux<String> flux = Flux.create(sink -> {
sink.next("Apple");
sink.next("Banana");
sink.next("Cherry");
sink.complete();
});
- Flux.generate():使用生成器函数逐个生成元素的 Flux。
Flux<Integer> flux = Flux.generate(() -> 0, (state, sink) -> {
if (state >= 5) {
sink.complete();
} else {
sink.next(state);
}
return state + 1;
});
Flux 的常见用法
订阅
要处理 Flux 中的元素,需要订阅它。订阅时可以提供回调函数,处理正常的元素、错误和完成事件。
Flux<String> flux = Flux.just("Apple", "Banana", "Cherry");
flux.subscribe(
item -> System.out.println("Received: " + item),
error -> System.err.println("Error: " + error.getMessage()),
() -> System.out.println("Completed")
);
变换
使用 map 和 flatMap 进行同步和异步的元素变换。
Flux<Integer> flux = Flux.just("Apple", "Banana", "Cherry")
.map(String::length);
过滤
使用 filter 方法根据条件过滤元素。
Flux<String> flux = Flux.just("Apple", "Banana", "Cherry")
.filter(fruit -> fruit.startsWith("A"));
合并
使用 merge 或 concat 将多个 Flux 合并为一个。
Flux<String> flux1 = Flux.just("Apple", "Banana");
Flux<String> flux2 = Flux.just("Cherry", "Date");
Flux<String> mergedFlux = Flux.merge(flux1, flux2);
Flux<String> concatenatedFlux = Flux.concat(flux1, flux2);
缓冲和窗口
使用 buffer 和 window 方法将元素分组到 List 或子 Flux。
Flux<List<String>> bufferedFlux =Flux.just("Apple", "Banana", "Cherry", "Date")
.buffer(2);
Flux<Flux<String>> windowedFlux = Flux.just("Apple", "Banana", "Cherry", "Date")
.window(2);
异常处理
使用 onErrorResume、onErrorReturn 和 retry 等方法处理错误。
Flux<String> flux = Flux.just("Apple", "Banana", "Cherry")
.map(fruit -> {
if ("Banana".equals(fruit)) {
throw new RuntimeException("Banana error");
}
return fruit.toUpperCase();
})
.onErrorResume(e -> Flux.just("Recovered"));
结论
本文介绍了如何使用 Project Reactor 的 Flux 类型创建响应式序列,并通过代码示例演示了 Flux 的常见用法。Flux 提供了一种强大和灵活的方式来处理异步数据流,使得响应式编程在 Java 应用程序中变得更加简单。