RxJava2.0简介(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Viiou/article/details/89359299

本文参考:https://www.jianshu.com/p/128e662906af

3.5 Map与FlatMap

Map与FlatMap是RxJava中的操作符。

那什么是操作符?

RxJava中的操作符就是为了提供函数式的特性,函数式最大的好处就是使得数据处理简洁易懂。操作符实质上就是RxJava函数式编程模式的体现。在我看来,函数就是变换关系的简称,比如在有一个数字集合A,又有一个数字集合B,从数字集合A变换到数字集合B的的这种关系,可以将其称为函数。

先看一下Map操作符。map是RxJava中最简单的一个变换操作符了,它的作用就是对上游发送的每一个事件应用一个函数,使得每一个事件都按照指定的函数去变化。用事件图表示如下:
在这里插入图片描述
图中的map函数将圆形事件变成了矩阵事件,在代码中,我们将int类型转变为String类型。

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        }).map(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) throws Exception {
                return "这是:" + integer;
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.i(TAG, s);
            }
        });

打印出的Log如下所示:

2019-04-25 17:15:07.747 30351-30351/? I/RxJavaTestHaHa: 这是:1
2019-04-25 17:15:07.747 30351-30351/? I/RxJavaTestHaHa: 这是:2
2019-04-25 17:15:07.747 30351-30351/? I/RxJavaTestHaHa: 这是:3

可以看到,我们在Observable中输入的是int类型,但是到了Consumer上,却变为了String类型,起作用的就是中间的map函数,它将String类型变为了int类型。

接下来是FlatMap操作符,这是一个很强大的操作符。

FlatMap将一个发送事件的上游的Observable,变为多个发送事件的Observable,然后将它们发射的事件合并后放进一个单独的Observable中。

形象的解释如下图所示,我们将一个圆事件变成正方形事件和三角形事件。

在这里插入图片描述

在这里插入图片描述
从上面两张图可以看到的是,上游的Observable每发送一个事件,faltMap都会创建一个新的水管,发送转换之后的事件,但是flatMap并不保证转换后事件的顺序性,并不能一定保证事件1在事件2的前面,如果需要顺序保证可以使用concatMap。

flatMap的示例代码如下所示:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }
        }).flatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                final List<String> list = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    list.add("Value is:" + integer + "  " + i);
                }
                return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.i(TAG, "accept: " + s);
            }
        });

打印出的Log如下所示,从log中可以看到,flatMap是不能保证顺序的。

2019-04-25 19:53:58.070 16442-16480/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:2  0
2019-04-25 19:53:58.070 16442-16480/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:2  1
2019-04-25 19:53:58.071 16442-16480/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:2  2
2019-04-25 19:53:58.071 16442-16481/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:3  0
2019-04-25 19:53:58.071 16442-16481/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:1  0
2019-04-25 19:53:58.071 16442-16481/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:1  1
2019-04-25 19:53:58.071 16442-16481/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:1  2
2019-04-25 19:53:58.071 16442-16481/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:3  1
2019-04-25 19:53:58.071 16442-16481/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:3  2

当时将代码改成下面这样,只是在Log中少打印i,但是打印出来的字符串却会发生变化。

代码如下所示:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }
        }).flatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                final List<String> list = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    list.add("Value is:" + integer);            //只是将这一行发生变换
                }
                return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.i(TAG, "accept: " + s);
            }
        });

打印出的Log则会变成如下这样:

2019-04-25 20:01:03.096 18724-18765/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:1
2019-04-25 20:01:03.096 18724-18765/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:1
2019-04-25 20:01:03.096 18724-18766/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:2
2019-04-25 20:01:03.096 18724-18766/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:2
2019-04-25 20:01:03.097 18724-18767/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:3
2019-04-25 20:01:03.097 18724-18767/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:3
2019-04-25 20:05:47.116 20344-20406/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:1
2019-04-25 20:05:47.116 20344-20406/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:1
2019-04-25 20:05:47.117 20344-20407/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:2
2019-04-25 20:05:47.117 20344-20408/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:3
2019-04-25 20:05:47.117 20344-20408/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:3
2019-04-25 20:05:47.117 20344-20407/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:2
2019-04-25 20:05:47.117 20344-20407/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:2

可以看到,打印出来的有的String漏掉了,为什么会变成这样,我也不是很清楚,先留个Todo在这里,以后解决一下这个问题。

flatMap写完之后也说一下前面提过的concatMap,它和flatMap几乎是一模一的,只不过concatMap是严格按照上游发送的顺序来发送的。

代码如下所示:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }
        }).concatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                List<String> stringList = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    stringList.add("Value is" + integer + "  " + i);
                }
                return Observable.fromIterable(stringList).delay(10, TimeUnit.MILLISECONDS);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.i(TAG, "accept: " + s);
            }
        });

上面提到的问题在下面依然存在,先看日志吧:

2019-04-25 20:16:59.878 22597-22655/? I/RxJavaTestHaHa: accept: Value is1  0
2019-04-25 20:16:59.878 22597-22655/? I/RxJavaTestHaHa: accept: Value is1  1
2019-04-25 20:16:59.878 22597-22655/? I/RxJavaTestHaHa: accept: Value is1  2
2019-04-25 20:16:59.888 22597-22659/? I/RxJavaTestHaHa: accept: Value is2  0
2019-04-25 20:16:59.889 22597-22659/? I/RxJavaTestHaHa: accept: Value is2  1
2019-04-25 20:16:59.889 22597-22659/? I/RxJavaTestHaHa: accept: Value is2  2
2019-04-25 20:16:59.901 22597-22662/? I/RxJavaTestHaHa: accept: Value is3  0
2019-04-25 20:16:59.902 22597-22662/? I/RxJavaTestHaHa: accept: Value is3  1
2019-04-25 20:16:59.902 22597-22662/? I/RxJavaTestHaHa: accept: Value is3  2

接下来是抓虫子的时间段了。

我将代码改成了下面这样,只是多了几条Log。

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }
        }).flatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                Log.i(TAG, "apply: interger is " + integer);
                List<String> list = new ArrayList<String>();
                for (int i = 0; i < 3; i++) {
                    list.add("Value is:" + integer);
                }
                Log.i(TAG, "apply: Size is " + list.size());
                for (String s : list) {
                    Log.i(TAG, s);
                }
                return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.i(TAG, "accept: " + s);
            }
        });

Log如下所示:

2019-04-25 21:25:06.553 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: apply: interger is 1
2019-04-25 21:25:06.553 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: apply: Size is 3
2019-04-25 21:25:06.553 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: Value is:1
2019-04-25 21:25:06.553 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: Value is:1
2019-04-25 21:25:06.557 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: apply: interger is 2
2019-04-25 21:25:06.558 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: apply: Size is 3
2019-04-25 21:25:06.558 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: Value is:2
2019-04-25 21:25:06.558 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: Value is:2
2019-04-25 21:25:06.558 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: apply: interger is 3
2019-04-25 21:25:06.558 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: apply: Size is 3
2019-04-25 21:25:06.558 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: Value is:3
2019-04-25 21:25:06.558 6670-6670/com.xupt.will.rxjavatest I/RxJavaTestHaHa: Value is:3
2019-04-25 21:25:06.567 6670-6739/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:1
2019-04-25 21:25:06.568 6670-6739/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:1
2019-04-25 21:25:06.568 6670-6740/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:2
2019-04-25 21:25:06.568 6670-6740/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:2
2019-04-25 21:25:06.568 6670-6741/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:3
2019-04-25 21:25:06.569 6670-6741/com.xupt.will.rxjavatest I/RxJavaTestHaHa: accept: Value is:3

在打印List的大小时还是正确的,但不知道为什么在遍历时出现这样的错误。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
额,断点调式查看List没有问题呀。Log与RxJava命数相冲?我在网上查阅资料时说RxJava在Android8.0 与Android9.0上不兼容,有可能是这个问题,不管怎么样,大体上RxJava还是正确的。

猜你喜欢

转载自blog.csdn.net/Viiou/article/details/89359299
今日推荐