Rxjava结合操作符

Rxjava操作符索引

这篇章主要介绍Rxjava的结合操作符

目录

CombineLatest

Join

Merge

StartWith

Concat

Switch

Zip


CombineLatest

上面是帮助文档的图片,接下来是我自己的描述。其实就是observable1每次发送数据的时候(除了第一个数据),都会与observable2发送的最近的一个数据结合后才发出去,而observable2每次发送数据的时候,都会与observable1最近发送的一个数据结合后才发出去。

Observable observable1 = Observable.intervalRange(1, 4, 0, 1000, TimeUnit.MILLISECONDS);
        Observable observable2 = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
                Thread.sleep(500);
                observableEmitter.onNext(7);
                Thread.sleep(2000);
                observableEmitter.onNext(8);
            }
        });

        Observable.combineLatest(observable1, observable2, new BiFunction<Long, Integer, String>() {
            @Override
            public String apply(Long num1, Integer num2) throws Throwable {
                return num1 +":"+ num2;
            }
        }).subscribe(s -> System.out.println(s));

结果:

1:7
2:7
3:7
3:8

结合我下面的时间轴和上面的描述就会 明白(1s为1秒)。当observable2发送完最后一个后就会停止了。

*               1s    1s   1s
* observable1 1————2————3————4
* observable2    7————————8

Join

任何时候,只要在另一个Observable发射的数据定义的时间窗口内,这个Observable发射了一条数据,就结合两个Observable发射的数据。这是帮助文档的描述,下面看一下代码,join的代码我都不写lambda,太难理解了,我都是写完整代码,lambda可以自己尝试些一下。

Observable observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
                observableEmitter.onNext(1);
                Thread.sleep(1000);
                observableEmitter.onNext(2);
                Thread.sleep(1000);
                observableEmitter.onNext(3);
                Thread.sleep(1000);
                observableEmitter.onNext(4);
            }
        });
        Observable observable2 = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
                observableEmitter.onNext(7);
                Thread.sleep(1000);
                observableEmitter.onNext(8);
            }
        });

        observable2.join(observable1, new Function<Integer, Observable>() {
            @Override
            public Observable apply(Integer o) throws Throwable {
                System.out.println(o+ "+");
                return Observable.timer(2000, TimeUnit.MILLISECONDS);
            }
        }, new Function<Integer, Observable>() {
            @Override
            public Observable apply(Integer o) throws Throwable {
                System.out.println(o+ "-");
                return Observable.empty();
            }
        }, new BiFunction<Integer, Integer, String>() {
            @Override
            public String apply(Integer num1, Integer num2) throws Throwable {
                return num1 +":"+ num2;
            }
        }).subscribe(s -> System.out.println(s));

结果:

7+
8+
1-
7:1
8:1
2-
8:2
3-
4-

代码有点多,首先observable1和observable2的代码应该不难懂,接下来我们看join的函数

第一个参数为要加入到哪个observable,二参是把observable2发送的每一个数据转换为一个observable,三参是把observable1发送的每一个数据转换为一个observable,四参是两个数据源进行结合的函数

        observable2.join(observable1, new Function<Integer, Observable>() {
            @Override
            public Observable apply(Integer o) throws Throwable {
                System.out.println(o+ "+");
                return Observable.timer(2000, TimeUnit.MILLISECONDS);
            }
        }, new Function<Integer, Observable>() {
            @Override
            public Observable apply(Integer o) throws Throwable {
                System.out.println(o+ "-");
                return Observable.empty();
            }
        }, new BiFunction<Integer, Integer, String>() {
            @Override
            public String apply(Integer num1, Integer num2) throws Throwable {
                return num1 +":"+ num2;
            }
        }).subscribe(s -> System.out.println(s));

上面代码可以看到,observable2的转换是Observable.timer(2000, TimeUnit.MILLISECONDS),就是让数据源延迟两秒发送,而对于observable1的转换是Observable.empty(),其实就是什么都没变正常发送。下面是时间轴(打印7简称y7,发送7简称7):

*                1s    1s   1s
* observable2 y7————y8————7————8
* observable1       1————2————3————4

所谓打印7,就是我们结果里面那个“7+”,就是进入我们转变observable2函数里面那句输出语句。为啥,合并函数里面只打印了7:1, 8:1, 8:2呢。

是这样的,observable1是在observable2所有数据都进入转变函数后才开始发送的,即在打印8的同时,observable1开始发送数据到自己那个转变函数。

而在打印7和发送7之间,第二个Observable发送了1(其中2和7算同时发,不包括在内),故输出了7:1

在打印8和发送8之间,第二个Observable发送了1,2(其中3和8算同时发,不包括在内),故输出了8:1,8:2

不知大家能不能明白,试一下,如果observable2我改成这样,会怎样

Observable observable2 = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
                observableEmitter.onNext(7);
                Thread.sleep(2000);
                observableEmitter.onNext(8);
            }
        });

现在揭晓,看看下面的时间轴就知道了,打印7和发送7之间没一个observable1的数据,而打印8和发送8之间有observable1发送的1和2,故结果是8:1, 8:2

*                   2s         2s
* observable2 y7————————y8和7————————8
* observable1              1————2————3————4

如果原来的代码想输出8:3应该怎么改,修改2和3之间的睡眠时间,如下我把2和3之间睡眠改成500毫秒

Observable observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
                observableEmitter.onNext(1);
                Thread.sleep(1000);
                observableEmitter.onNext(2);
                Thread.sleep(500);
                observableEmitter.onNext(3);
                Thread.sleep(1000);
                observableEmitter.onNext(4);
            }
        });

时间轴就变成这样,故会输出7:1, 8:1, 8:2, 8:3

*                1s    1s   1s
* observable2 y7————y8————7————8
* observable1        1————2——3————4

Merge

这个很简单就是两个observable按照他们发送的时间轴合并成一个observable发送,文字描述也有点含糊,看代码

        Observable observable1 = Observable.intervalRange(5, 3, 500, 1000, TimeUnit.MILLISECONDS);
        Observable observable2 = Observable.intervalRange(1, 4, 0, 1000, TimeUnit.MILLISECONDS, Schedulers.trampoline());
        Observable.merge(observable1, observable2).subscribe(num -> System.out.println(num+"*"));

intervalRange是什么,可以看回之前的那篇创建操作符。observable1和observable2我们要设置在不同的时间调度上,要是他们两个在同个线程,他们会按顺序先后发送,时间轴不会重叠起来。

上面observable1,就是从5开始发送,一个发送3个数字(那就是要发送5,6,7了),延迟500毫秒发送,每1秒发一次。observable2就是从1开始,发送4个数字,不延迟,每隔1秒发一次。时间轴就是:

*                1s   1s  
*observable1   5————6————7
*observable2 1————2————3————4

故结果:

1*
5*
2*
6*
3*
7*
4*

StartWith

在数据序列的开头插入指定的项

Observable observable1 = Observable.just(1,2,3,4);
        observable1.startWithArray(-1,-2,-3).subscribe(num -> System.out.println(num+""));

结果:

-1
-2
-3
1
2
3
4

除了startWithArray放入数组以外,startWithItem只放入一个item,startWithIterable放入列表,startWith放入observable,就不一一代码展示。

Concat

简单一句就是跟startWith相反,在数据序列的结尾插入指定项,不过它只能放入observable

Observable observable1 = Observable.just(1,2,3,4);
        Observable observable2 = Observable.just(-1,-2,-3,-4);

        observable1.concatWith(observable2).subscribe(num -> System.out.println(num+""));

结果:

1
2
3
4
-1
-2
-3
-4

Switch

下面只说switchIfEmpty,其他还没研究

Observable observable1 = Observable.just(1,2,3);
        Observable observable2 = Observable.just(4,5,6);
        observable1.switchIfEmpty(observable2).subscribe(num -> System.out.println(num+""));

结果:

1
2
3

代码改成这样的话

Observable observable1 = Observable.empty();
        Observable observable2 = Observable.just(4,5,6);
        observable1.switchIfEmpty(observable2).subscribe(num -> System.out.println(num+""));

结果:

4
5
6

其实很容易理解,就是一个判空操作,如果observable1不是空,就正常输出observable1,如果observable1为空,就输出我们设置好的observable2。

Zip

zipWith将两个数据源1对1地合并,合并数据源数据比较少的一方的个数(如一个数据源有4个数据,一个数据源只有3个数据,那么只会合并两个数据源的前3个数据)

Observable observable1 = Observable.just(1,2,3);
        List<Integer> list = Arrays.asList(4,5,6);
        observable1.zipWith(list, new BiFunction<Integer, Integer, String>() {
            @Override
            public String apply(Integer o, Integer o2) throws Throwable {
                return o+":"+o2;
            }
        }).subscribe(num -> System.out.println(num+""));

结果:

1:4
2:5
3:6

上面ZipWith的一参为另一数据源,二参为合并函数。上面的一参除了放列表,还可以放observable

Observable observable2 = Observable.just(4,5,6);
        observable1.zipWith(observable2, (num1, num2) -> num1+":"+num2)
        .subscribe(num -> System.out.println(num+""));

结果跟上面一样,就不写了。

发布了17 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/DNWalter/article/details/102765179