专业的JAVA编程教程与资源

网站首页 > java教程 正文

SpringCloudRPC核心原理:RxJava响应式编程框架,转换型操作符

temp10 2024-12-03 18:31:55 java教程 16 ℃ 0 评论

转换型操作符

本节介绍RxJava的3个转换型操作符:map操作符、flatMap操作符和scan操作符。

map操作符

map操作符接受一个转换函数,对Observable弹射的消息流中的每一个元素应用该转换函数,转换之后的结果从消息流弹出。map操作符返回的消息流由转换函数执行转换之后的结果组成。

SpringCloudRPC核心原理:RxJava响应式编程框架,转换型操作符

map操作符的处理流程如图4-6所示。

map操作符需要接收一个函数式接口Function<T,R>的对象,该对象实现了接口的apply(T)方法,此方法负责对接收到的实参进行转换,返回转换之后的新值。

map操作符的使用实例如下:

package com.crazymaker.demo.rxJava.basic;
//省略import
@Slf4j
public class TransformationDemo
{
 /**
*演示map转换
*/
 @Test
 public void mapDemo() {
 Observable.range(1, 4)
 .map(i -> i *i)
 .subscribe(i -> log.info(i.toString()));
 }
...
}

运行这个演示程序,输出的结果如下:

[main] INFO c.c.d.r.b.TransformationDemo - 1
[main] INFO c.c.d.r.b.TransformationDemo - 4
[main] INFO c.c.d.r.b.TransformationDemo - 9
[main] INFO c.c.d.r.b.TransformationDemo - 16

map操作符从消息流中取一个值,然后返回另一个值,转换的逻辑是一对一的,而flatMap操作符的逻辑并不是如此。

flatMap操作符

flatMap操作符将输入消息流的任意数量的元素(零项或无穷项)打包成一个新的Observable主题然后弹出。

flatMap操作符的处理流程如图4-7所示。

flatMap操作符将一个弹射数据的Observable流变换为一个弹射Observable主题对象的新流,新流所弹出的主题对象(元素)会包含源流中的一个或者多个数据元素,其特点如下:

(1)flatMap转换是一对一类型或者一对多类型的,原来弹射了几个数据,转换之后可以是更多个数据。

(2)flatMap转换同样可以改变弹射的数据类型。

(3)flatMap转换后的数据还是会逐个发射给下游的Subscriber来接收,表面上就像这些数据是由一个Observable发射的一样,其实是多个Observable发射然后合并的。一个简单的flatMap操作符的使用实例如下:

package com.crazymaker.demo.rxJava.basic;
//省略import
@Slf4j
public class TransformationDemo
{
 ...
 /**
 *演示flapMap转换
 */
 @Test
 public void flapMapDemo()
 {
 /**
 *注意 flatMap 中的just创建的是一个新流
 */
 Observable.range(1, 4)
 .flatMap(i -> Observable.just(i *i, i *i + 1))
 .subscribe(i -> log.info(i.toString()));
 }
}

运行这个演示程序,输出的结果如下:

[main] INFO c.c.d.r.b.TransformationDemo - 1
[main] INFO c.c.d.r.b.TransformationDemo - 2
[main] INFO c.c.d.r.b.TransformationDemo - 4
[main] INFO c.c.d.r.b.TransformationDemo - 5
[main] INFO c.c.d.r.b.TransformationDemo - 9
[main] INFO c.c.d.r.b.TransformationDemo - 10
[main] INFO c.c.d.r.b.TransformationDemo - 16
[main] INFO c.c.d.r.b.TransformationDemo - 17

由于在转换的过程中flatMap操作符创建了新的Observable主题对象,因此其可以被归类为创建型操作符。一个更复杂的flatMap操作符的使用实例如下:

package com.crazymaker.demo.rxJava.basic;
//省略import
@Slf4j
public class TransformationDemo
{
 ...
 /**
 *演示一个稍微复杂的flapMap转换
 */
 @Test public void flapMapDemo2()
 {
 Observable.range(1, 4)
 .flatMap(i -> Observable.range(1, i).toList())
 .subscribe(list -> log.info(list.toString()));
 }
}

在这个使用实例中,flatMap把输入流的元素通过range创建型操作符转成一个Observable对象,然后调用其toList()方法转换成包装单个List元素的新Observable主题对象并弹出。运行这个演示程序,输出的结果如下:

[main] INFO c.c.d.r.b.TransformationDemo - [1]
[main] INFO c.c.d.r.b.TransformationDemo - [1, 2]
[main] INFO c.c.d.r.b.TransformationDemo - [1, 2, 3]
[main] INFO c.c.d.r.b.TransformationDemo - [1, 2, 3, 4]

scan操作符

scan操作符对一个Observable流序列的每一项数据应用一个累积函数,然后将这个函数的累积结果弹射出去。除了第一项之外,scan操作符会将上一个数据项的累积结果作为下一个数据项在应用累积函数时的输入,所以scan操作符有点类似递归操作。

假定累积函数为一个简单的累加函数,然后使用scan操作符对1~5的数据流序列进行扫描,它的执行流程如图4-8所示。

使用scan操作符对1~5的数据流序列进行扫描,并使用累加函数进行累加,参考如下的实现代码:

package com.crazymaker.demo.rxJava.basic;
//省略import
@Slf4j
public class TransformationDemo
{
 /**演示scan操作符扫描*/
 @Test
 public void scanDemo()
 {
 /**定义一个accumulator累积函数 */
 Func2<Integer, Integer, Integer> accumulator = new Func2<Integer, Integer, Integer>()
 {
 @Override
 public Integer call(Integer input1, Integer input2)
 {
 log.info(" {} + {} = {} ", input1, input2, input1 + input2);
 return input1 + input2; }
 };
 /**
 *使用scan进行流扫描
 */
 Observable.range(1, 5)
 .scan(accumulator)
 .subscribe(new Action1<Integer>()
 {
 @Override
 public void call(Integer sum)
 {
 log.info(" 累加的结果: {} ", sum);
 }
 });
 }
}

运行以上代码,输出的结果节选如下:

[main] INFO c.c.d.r.b.TransformationDemo - 累加的结果: 1
[main] INFO c.c.d.r.b.TransformationDemo - 1 + 2 = 3
[main] INFO c.c.d.r.b.TransformationDemo - 累加的结果: 3
[main] INFO c.c.d.r.b.TransformationDemo - 3 + 3 = 6
[main] INFO c.c.d.r.b.TransformationDemo - 累加的结果: 6
[main] INFO c.c.d.r.b.TransformationDemo - 6 + 4 = 10
[main] INFO c.c.d.r.b.TransformationDemo - 累加的结果: 10
[main] INFO c.c.d.r.b.TransformationDemo - 10 + 5 = 15
[main] INFO c.c.d.r.b.TransformationDemo - 累加的结果: 15

以上实例中,scan操作符对原Observable流所弹射的第一项数据1应用了accumulator累积函数,然后将累积函数的结果1作为输出流的第一项数据弹射出去;接下来,它将第一个结果连同原始Observable流的第二项数据2一起,再填充给accumulator累积函数,之后将累积结果3作为输出流的第二项数据弹射出去。scan操作符持续重复这个过程,不断对原流进行累积,直到其最后一个数据项的累积结果从输出流弹射出去。

本文给大家讲解的内容是SpringCloudRPC远程调用核心原理: RxJava响应式编程框架,转换型操作符

  1. 下篇文章给大家讲解的是SpringCloudRPC远程调用核心原理: RxJava响应式编程框架,聚合操作符;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表