Rxjava2操作符

RxJava2操作符

just

输入什么,输出什么

Observable.just("Hello world").subscribe(s -> showLog(s));

打印Log:

01-17 00:46:17.140 1156-1156/com.xiey94.rxjava2 E/ccer: Hello world

fromArray

将输入的数组都发射出来

Observable.fromArray("Hello", "World", "girl").subscribe(s -> showLog(s));

打印Log:

01-17 00:52:23.968 1250-1250/com.xiey94.rxjava2 E/ccer: Hello
01-17 00:52:23.968 1250-1250/com.xiey94.rxjava2 E/ccer: World
01-17 00:52:23.968 1250-1250/com.xiey94.rxjava2 E/ccer: girl

fromIterable

遍历发射一个实现了迭代器接口的数组

ArrayList<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");

        Observable.fromIterable(list).subscribe(s -> showLog(s));

打印Log:

01-17 01:02:41.016 1370-1370/com.xiey94.rxjava2 E/ccer: A
01-17 01:02:41.016 1370-1370/com.xiey94.rxjava2 E/ccer: B
01-17 01:02:41.016 1370-1370/com.xiey94.rxjava2 E/ccer: C

map

登录注册常见写法:

protected void login() {
        api.login(new LoginRequest())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(loginResponse -> showToast("登陆成功")
                        , throwable -> showToast("登陆失败"));
    }

    protected void register() {
        api.register(new RegisterRequest())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(registerResponse -> {
                    showToast("注册成功");
                    //注册成功后登陆
                    login();
                }, throwable -> showToast("注册失败"));
    }

以上不够优雅

map变换:

//map转换
        Observable.create(e -> {
            e.onNext(1);
            e.onNext(2);
            e.onNext(3);
        }).map(integer -> "This is result " + integer
        ).subscribe(s -> showLog(s));

将Integer->String,最终打印

打印Log:

01-15 14:35:03.805 2390-2390/? E/ccer: This is result 1
01-15 14:35:03.805 2390-2390/? E/ccer: This is result 2
01-15 14:35:03.805 2390-2390/? E/ccer: This is result 3

flatMap

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

//flatMap转换
        Observable.create(e -> {
            e.onNext(1);
            e.onNext(2);
            e.onNext(3);
        }).flatMap(integer -> {
            final List<String> list = new ArrayList<>();
            for (int i = 0; i < 3; i++) {
                list.add("I am value " + integer);
            }
            return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
        }).subscribe(s -> showLog(s));

打印Log:

01-15 14:47:40.393 2525-2539/? E/ccer: I am value 1
01-15 14:47:40.393 2525-2539/? E/ccer: I am value 1
01-15 14:47:40.393 2525-2539/? E/ccer: I am value 1
01-15 14:47:40.393 2525-2539/? E/ccer: I am value 2
01-15 14:47:40.393 2525-2539/? E/ccer: I am value 2
01-15 14:47:40.393 2525-2539/? E/ccer: I am value 2
01-15 14:47:40.401 2525-2539/? E/ccer: I am value 3
01-15 14:47:40.401 2525-2539/? E/ccer: I am value 3
01-15 14:47:40.401 2525-2539/? E/ccer: I am value 3

上游发了三个事件,然后每个分发为3个,将Integer->String,并打印出来。

用flatMap完成一开始的那个不优雅的请求

protected void register2() {
        api.register(new RegisterRequest())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(registerResponse -> {
                    //根据注册结果响应一些操作
                }).observeOn(Schedulers.io())//回到IO线程去发起登陆请求
                .flatMap(registerResponse -> {
                    //将注册成功的参数作为登录的参数(账号面等等)用于登录的准备
                    api.login(new LoginRequest());
                }).observeOn(AndroidSchedulers.mainThread())//回到主线程去处理请求登陆的结果
                .subscribe(loginResponse -> showToast("登陆成功")
                        , throwable -> showToast("登陆失败"));
    }

为什么一对一不用map而用flatMap?

因为flatmap能转化发射源,既“Observable” -> “Observable” ,配合Retrofit就能在完成注册事件后继续完成登录事件。

map操作符只能把“Observable”里面的“RegisterResponse”转化成“LoginResponse”,而“LoginResponse”只是一个model对象,不能作为发射源完成登录操作

concatMap

作用同flatMap,唯一的不同点就是flatMap的结果是无序的,我上面的Log看起来有序,只是一个偶然;concatMap同flatMap的用法,只是它返回的是有序的,按照上游发送的顺序来排序。

zip

Zip通过一个函数将多个Observable发送的事件结合到一起,然后发送这些组合到一起的事件. 它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable一样多的数据。

 //zip
        Observable observable1 = Observable.create(e -> {
            showLog("emit 1");
            e.onNext(1);
            showLog("emit 2");
            e.onNext(2);
            showLog("emit 3");
            e.onNext(3);
            showLog("emit 4");
            e.onNext(4);
            showLog("emit complete");
            e.onComplete();
        }).subscribeOn(Schedulers.io());

        Observable observable2 = Observable.create(e -> {
            showLog("emit A");
            e.onNext("A");
            showLog("emit B");
            e.onNext("B");
            showLog("emit C");
            e.onNext("C");
            showLog("emit complete");
            e.onComplete();
        }).subscribeOn(Schedulers.io());

        Observable.zip(observable1, observable2, (Integer integer, String s) -> integer + s
        ).subscribe(new Observer() {
            @Override
            public void onSubscribe(Disposable d) {
                showLog("onSubscribe");
            }

            @Override
            public void onNext(Object value) {
                showLog("onNext: " + value);
            }

            @Override
            public void onError(Throwable e) {
                showLog("onError");
            }

            @Override
            public void onComplete() {
                showLog("onComplete");
            }
        });

打印Log:

01-16 01:48:07.013 1285-1285/? E/ccer: onSubscribe
01-16 01:48:07.013 1285-1299/? E/ccer: emit 1
01-16 01:48:07.021 1285-1299/? E/ccer: emit 2
01-16 01:48:07.021 1285-1299/? E/ccer: emit 3
01-16 01:48:07.025 1285-1299/? E/ccer: emit 4
01-16 01:48:07.025 1285-1299/? E/ccer: emit complete
01-16 01:48:07.025 1285-1300/? E/ccer: emit A
01-16 01:48:07.025 1285-1300/? E/ccer: onNext: 1A
01-16 01:48:07.025 1285-1300/? E/ccer: emit B
01-16 01:48:07.025 1285-1300/? E/ccer: onNext: 2B
01-16 01:48:07.025 1285-1300/? E/ccer: emit C
01-16 01:48:07.025 1285-1300/? E/ccer: onNext: 3C
01-16 01:48:07.025 1285-1300/? E/ccer: emit complete
01-16 01:48:07.025 1285-1300/? E/ccer: onComplete

可以看出是在组合两个为一个;很明显我加了线程调度,但是Log中显示是先事件流1,然后事件流2的顺序来的,其实不然,主要是这事件不耗时,一瞬间就跑没了。至于事件流1中为什么onNext(4)事件没有组合消耗,很正常,4男3女组合结婚,总的剩下一个。

水管中组合用户信息:

    protected void getUserInfo() {
        Observable<UserBaseInfoResponse> observable1 = api.getUserBaseInfo(new UserBaseInfoRequest()).subscribeOn(Schedulers.io());
        Observable<UserExtraInfoResponse> observable2 = api.getUserExtraInfo(new UserExtraInfoRequest()).subscribeOn(Schedulers.io());
        Observable.zip(observable1, observable2, (UserBaseInfoResponse userBaseInfo, UserExtraInfoResponse userExtraInfo) -> new UserInfo(userBaseInfo, userExtraInfo))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(userInfo -> {
                    //do something

                });
    }

filter

过滤:

Observable.create(e -> {
            for (int i = 0; i < 100; i++) {
                e.onNext(i);
            }
        }).subscribeOn(Schedulers.io())
                .filter((integer) -> ((Integer) integer) % 10 == 0)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(s -> {
                    showLog("" + s);
                });

打印Log:

01-16 03:27:19.305 2407-2407/? E/ccer: 0
01-16 03:27:19.305 2407-2407/? E/ccer: 10
01-16 03:27:19.305 2407-2407/? E/ccer: 20
01-16 03:27:19.305 2407-2407/? E/ccer: 30
01-16 03:27:19.305 2407-2407/? E/ccer: 40
01-16 03:27:19.305 2407-2407/? E/ccer: 50
01-16 03:27:19.305 2407-2407/? E/ccer: 60
01-16 03:27:19.305 2407-2407/? E/ccer: 70
01-16 03:27:19.305 2407-2407/? E/ccer: 80
01-16 03:27:19.309 2407-2407/? E/ccer: 90

sample/throttleLast

取样,在上游中每隔一段事件取出一个放到下游或者水缸;

Observable.create(e -> {
            for (int i = 0; ; i++) {
                e.onNext(i);
            }
        }).subscribeOn(Schedulers.io())
                .sample(2, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(s -> {
                    showLog("" + s);
                });

打印Log:

01-16 11:31:51.187 16400-16400/com.xiey94.rxjava2 E/ccer: 2374518
01-16 11:31:53.184 16400-16400/com.xiey94.rxjava2 E/ccer: 4730215
01-16 11:31:55.184 16400-16400/com.xiey94.rxjava2 E/ccer: 7121610
01-16 11:31:57.184 16400-16400/com.xiey94.rxjava2 E/ccer: 9484672
01-16 11:31:59.184 16400-16400/com.xiey94.rxjava2 E/ccer: 11853821
01-16 11:32:01.184 16400-16400/com.xiey94.rxjava2 E/ccer: 14828915
01-16 11:32:03.184 16400-16400/com.xiey94.rxjava2 E/ccer: 17808886
...

take

指定最多发射多少个事件

Observable.fromArray("A", "B", "C", "D").take(2).subscribe(s -> showLog(s));

打印Log:

01-17 01:11:47.796 1539-1539/? E/ccer: A
01-17 01:11:47.796 1539-1539/? E/ccer: B

do系列

Observable
                .fromArray("A", "B", "C", "D")
                .doOnNext(s -> showLog("doOnNext " + s))
                .doAfterNext(s -> showLog("doAfterNext " + s))
                .doOnComplete(() -> showLog("doOnComplete "))
                .doFinally(() -> showLog("doFinally "))//在onError和或onCompleted后调用指定的操作,或由下游处理。
                .doOnError(throwable -> showLog("doOnError " + throwable))
                .doOnDispose(() -> showLog("doOnDispose "))//出现completeerror的时候 dispose才会触发
                .doOnEach(stringNotification -> showLog("doOnEach " + stringNotification))//Observable每发射一个数据的时候就会触发这个回调,不仅包括onNext还包括onErroronCompleted
                .doOnTerminate(() -> showLog("doOnTerminate "))//会在Observable结束前触发回调,无论是正常还是异常终止。
                .doAfterTerminate(() -> showLog("doAfterTerminate "))//会在Observable结束后触发回调,无论是正常还是异常终止。
                .doOnLifecycle(disposable -> showLog("doOnLifecycle-disposable " + disposable)
                        , () -> showLog("doOnLifecycle "))//可以在订阅之后 设置是否取消订阅
                .doOnSubscribe(disposable -> showLog("doOnSubscribe " + disposable))//进行订阅的时候
                .subscribe(s -> showLog(s));

打印的Log:

01-17 01:39:45.244 1888-1888/? E/ccer: doOnLifecycle-disposable io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver@5367a788
01-17 01:39:45.244 1888-1888/? E/ccer: doOnSubscribe io.reactivex.internal.observers.DisposableLambdaObserver@536817f8
01-17 01:39:45.244 1888-1888/? E/ccer: doOnNext A
01-17 01:39:45.244 1888-1888/? E/ccer: doOnEach OnNextNotification[A]
01-17 01:39:45.244 1888-1888/? E/ccer: A
01-17 01:39:45.244 1888-1888/? E/ccer: doAfterNext A
01-17 01:39:45.244 1888-1888/? E/ccer: doOnNext B
01-17 01:39:45.244 1888-1888/? E/ccer: doOnEach OnNextNotification[B]
01-17 01:39:45.244 1888-1888/? E/ccer: B
01-17 01:39:45.244 1888-1888/? E/ccer: doAfterNext B
01-17 01:39:45.244 1888-1888/? E/ccer: doOnNext C
01-17 01:39:45.244 1888-1888/? E/ccer: doOnEach OnNextNotification[C]
01-17 01:39:45.244 1888-1888/? E/ccer: C
01-17 01:39:45.244 1888-1888/? E/ccer: doAfterNext C
01-17 01:39:45.244 1888-1888/? E/ccer: doOnNext D
01-17 01:39:45.244 1888-1888/? E/ccer: doOnEach OnNextNotification[D]
01-17 01:39:45.244 1888-1888/? E/ccer: D
01-17 01:39:45.244 1888-1888/? E/ccer: doAfterNext D
01-17 01:39:45.244 1888-1888/? E/ccer: doOnComplete 
01-17 01:39:45.244 1888-1888/? E/ccer: doOnEach OnCompleteNotification
01-17 01:39:45.244 1888-1888/? E/ccer: doOnTerminate 
01-17 01:39:45.244 1888-1888/? E/ccer: doOnLifecycle 
01-17 01:39:45.244 1888-1888/? E/ccer: doOnDispose 
01-17 01:39:45.244 1888-1888/? E/ccer: doFinally 
01-17 01:39:45.244 1888-1888/? E/ccer: doAfterTerminate 

可以参照回调的先后顺序来除了一些事情。

repeat

重复的发送

不停的重复:

Observable.just("Hello", "World", "girl")
                .repeat()
                .subscribe(s -> showLog(s));

打印Log:

01-17 01:50:35.392 2014-2014/com.xiey94.rxjava2 E/ccer: Hello
01-17 01:50:35.392 2014-2014/com.xiey94.rxjava2 E/ccer: World
01-17 01:50:35.392 2014-2014/com.xiey94.rxjava2 E/ccer: girl
01-17 01:50:35.392 2014-2014/com.xiey94.rxjava2 E/ccer: Hello
01-17 01:50:35.392 2014-2014/com.xiey94.rxjava2 E/ccer: World
01-17 01:50:35.392 2014-2014/com.xiey94.rxjava2 E/ccer: girl
01-17 01:50:35.432 2014-2014/com.xiey94.rxjava2 E/ccer: World
01-17 01:50:35.432 2014-2014/com.xiey94.rxjava2 E/ccer: girl
...

有次数的重复:

Observable.just("Hello", "World", "girl")
                .repeat(3)
                .subscribe(s -> showLog(s));

打印Log:

01-17 01:53:04.520 2084-2084/? E/ccer: Hello
01-17 01:53:04.520 2084-2084/? E/ccer: World
01-17 01:53:04.520 2084-2084/? E/ccer: girl
01-17 01:53:04.520 2084-2084/? E/ccer: Hello
01-17 01:53:04.520 2084-2084/? E/ccer: World
01-17 01:53:04.520 2084-2084/? E/ccer: girl
01-17 01:53:04.520 2084-2084/? E/ccer: Hello
01-17 01:53:04.520 2084-2084/? E/ccer: World
01-17 01:53:04.520 2084-2084/? E/ccer: girl

repeatUntil

动态控制重复次数,如果返回true则不重复了,否则接着重复发送事件

Observable.just("Hello", "World", "girl")
                .repeatUntil(() -> {
                    count++;
                    if (count == 2) {
                        return true;
                    }
                    return false;
                }).subscribe(s -> showLog(s));

打印Log:

01-17 01:58:31.768 2178-2178/com.xiey94.rxjava2 E/ccer: Hello
01-17 01:58:31.768 2178-2178/com.xiey94.rxjava2 E/ccer: World
01-17 01:58:31.768 2178-2178/com.xiey94.rxjava2 E/ccer: girl
01-17 01:58:31.768 2178-2178/com.xiey94.rxjava2 E/ccer: Hello
01-17 01:58:31.768 2178-2178/com.xiey94.rxjava2 E/ccer: World
01-17 01:58:31.768 2178-2178/com.xiey94.rxjava2 E/ccer: girl

range

指定一个范围,两个参数:第一个是开始的位置,第二个是总次数

Observable.range(4, 6).subscribe(integer -> showLog("" + integer));

打印Log:

01-17 02:01:53.376 2311-2311/? E/ccer: 4
01-17 02:01:53.376 2311-2311/? E/ccer: 5
01-17 02:01:53.376 2311-2311/? E/ccer: 6
01-17 02:01:53.376 2311-2311/? E/ccer: 7
01-17 02:01:53.376 2311-2311/? E/ccer: 8
01-17 02:01:53.376 2311-2311/? E/ccer: 9

rangeLong

和上面那个差不多,不过次数可以是个超长的数字

intervalRange

更加精细一点:第一个是起始位置,第二个是次数,第三个是等待多少时间开始,第四个是每隔多少时间发射一次,第五个是时间单位,第六个是线程调度器

Observable
                .intervalRange(4, 6, 3, 1, TimeUnit.SECONDS)
                .subscribe(integer -> showLog("" + integer));
Observable
                .intervalRange(4, 6, 3, 1, TimeUnit.SECONDS,Schedulers.io())
                .subscribe(integer -> showLog("" + integer));

打印Log:

这里写图片描述

可以用这个做一个倒计时:

Observable
                .intervalRange(0, 60, 0, 1, TimeUnit.SECONDS, Schedulers.io())
                .map((Long aLong) -> 60 - aLong)
                .map((Long aLong) -> "" + aLong)
                .subscribe(s -> showLog(s));

当然这个是打印版的,如果显示到View上,就得加上线程调度了。如果Activity临时退出,可以在开关那关掉开关(Disposable)

delay

延迟一段时间后发射:

Observable
                .range(4, 6)
                .delay(2, TimeUnit.SECONDS)
                .subscribe(integer -> showLog("" + integer));

打印Log:

延迟2秒后打印出:

01-17 02:55:08.936 2996-3011/com.xiey94.rxjava2 E/ccer: 4
01-17 02:55:08.936 2996-3011/com.xiey94.rxjava2 E/ccer: 5
01-17 02:55:08.936 2996-3011/com.xiey94.rxjava2 E/ccer: 6
01-17 02:55:08.936 2996-3011/com.xiey94.rxjava2 E/ccer: 7
01-17 02:55:08.936 2996-3011/com.xiey94.rxjava2 E/ccer: 8
01-17 02:55:08.936 2996-3011/com.xiey94.rxjava2 E/ccer: 9

delaySubscription

延迟订阅Observable,同上面有区别,上面是延迟发射,下面是延迟订阅。

materialize

将Observable转换成一个通知列表。

Observable
                .range(4, 6)
                .materialize()
                .subscribe(integer -> showLog("" + integer));

打印Log:

01-17 03:07:51.980 3227-3227/com.xiey94.rxjava2 E/ccer: OnNextNotification[4]
01-17 03:07:51.980 3227-3227/com.xiey94.rxjava2 E/ccer: OnNextNotification[5]
01-17 03:07:51.980 3227-3227/com.xiey94.rxjava2 E/ccer: OnNextNotification[6]
01-17 03:07:51.980 3227-3227/com.xiey94.rxjava2 E/ccer: OnNextNotification[7]
01-17 03:07:51.984 3227-3227/com.xiey94.rxjava2 E/ccer: OnNextNotification[8]
01-17 03:07:51.984 3227-3227/com.xiey94.rxjava2 E/ccer: OnNextNotification[9]
01-17 03:07:51.984 3227-3227/com.xiey94.rxjava2 E/ccer: OnCompleteNotification

dematerialize

与上面的作用相反,将通知逆转回一个Observable。

这两个我并不知道能用于何处,只是照搬过来。

forEach

简化版的 subscribe,但是没法取消订阅,可用于简单的数据处理。

Observable
                .range(4, 6)
                .forEach(integer -> showLog("" + integer));

serialize

保证上游下游同一线程 ,防止不同线程下onError通知会跳到(并吞掉)原始Observable发射的数据项前面的错误行为

Timestamp

它将一个发射T类型数据的Observable转换为一个发射类型为Timestamped的数据的Observable,每一项都包含数据的原始发射时间

Observable
                .range(4, 6)
                .timestamp()
                .subscribe(integer -> showLog("" + integer));

打印Log:

01-17 03:18:15.220 3406-3406/? E/ccer: Timed[time=1516159095224, unit=MILLISECONDS, value=4]
01-17 03:18:15.220 3406-3406/? E/ccer: Timed[time=1516159095224, unit=MILLISECONDS, value=5]
01-17 03:18:15.220 3406-3406/? E/ccer: Timed[time=1516159095224, unit=MILLISECONDS, value=6]
01-17 03:18:15.220 3406-3406/? E/ccer: Timed[time=1516159095224, unit=MILLISECONDS, value=7]
01-17 03:18:15.220 3406-3406/? E/ccer: Timed[time=1516159095224, unit=MILLISECONDS, value=8]
01-17 03:18:15.220 3406-3406/? E/ccer: Timed[time=1516159095224, unit=MILLISECONDS, value=9]

interval

创建一个按固定时间间隔发射整数序列的Observable

间隔1秒发射一个,只发射10个

Observable
                .interval(1, TimeUnit.SECONDS)
                .take(10)
                .doOnComplete(() -> showLog("doOnComplete"))
                .subscribe(integer -> showLog("" + integer));

打印Log:

01-17 03:26:38.164 3791-3806/com.xiey94.rxjava2 E/ccer: 0
01-17 03:26:39.168 3791-3806/com.xiey94.rxjava2 E/ccer: 1
01-17 03:26:40.168 3791-3806/com.xiey94.rxjava2 E/ccer: 2
01-17 03:26:41.164 3791-3806/com.xiey94.rxjava2 E/ccer: 3
01-17 03:26:42.168 3791-3806/com.xiey94.rxjava2 E/ccer: 4
01-17 03:26:43.168 3791-3806/com.xiey94.rxjava2 E/ccer: 5
01-17 03:26:44.168 3791-3806/com.xiey94.rxjava2 E/ccer: 6
01-17 03:26:45.168 3791-3806/com.xiey94.rxjava2 E/ccer: 7
01-17 03:26:46.168 3791-3806/com.xiey94.rxjava2 E/ccer: 8
01-17 03:26:47.168 3791-3806/com.xiey94.rxjava2 E/ccer: 9
01-17 03:26:47.168 3791-3806/com.xiey94.rxjava2 E/ccer: doOnComplete

timeInterval

一个发射数据的Observable转换为发射那些数据发射时间间隔的Observable

Observable
                .range(4,6)
                .timeInterval()
                .subscribe(integer -> showLog("" + integer));

打印Log:

01-17 04:02:32.488 4088-4088/? E/ccer: Timed[time=0, unit=MILLISECONDS, value=4]
01-17 04:02:32.488 4088-4088/? E/ccer: Timed[time=0, unit=MILLISECONDS, value=5]
01-17 04:02:32.488 4088-4088/? E/ccer: Timed[time=0, unit=MILLISECONDS, value=6]
01-17 04:02:32.488 4088-4088/? E/ccer: Timed[time=0, unit=MILLISECONDS, value=7]
01-17 04:02:32.488 4088-4088/? E/ccer: Timed[time=0, unit=MILLISECONDS, value=8]
01-17 04:02:32.488 4088-4088/? E/ccer: Timed[time=0, unit=MILLISECONDS, value=9]

timeout

过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),它会发一个错误

Observable
                .interval(2, TimeUnit.SECONDS)
                .timeout(1, TimeUnit.SECONDS)
                .subscribe(integer -> showLog("" + integer), throwable -> showLog("" + throwable));

打印Log:

01-17 04:06:31.612 4235-4249/com.xiey94.rxjava2 E/ccer: java.util.concurrent.TimeoutException

cast

在发射之前强制将Observable发射的所有数据转换为指定类型

Observable
                .just(1,2,"string")
                .cast(Integer.class)
                .subscribe(integer -> showLog("" + integer), throwable -> showLog("" + throwable));

打印Log:

01-17 04:08:22.740 4309-4309/? E/ccer: 1
01-17 04:08:22.740 4309-4309/? E/ccer: 2
01-17 04:08:22.740 4309-4309/? E/ccer: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

groupBy

通过keySelector的apply的值当做key进行分组,发射GroupedObservable(有getKey()方法)的group通过group继续订阅取得其组内的值;

Observable
                .range(4, 6)
                .groupBy(new Function<Integer, String>() {
                    @Override
                    public String apply(Integer integer) throws Exception {
                        return "" + integer;
                    }
                })
                .subscribe(group -> {
                    group.subscribe(integer -> showLog("" + group.getKey() + "----" + integer));
                });

打印Log:

01-17 06:01:55.332 5268-5268/com.xiey94.rxjava2 E/ccer: 4----4
01-17 06:01:55.336 5268-5268/com.xiey94.rxjava2 E/ccer: 5----5
01-17 06:01:55.336 5268-5268/com.xiey94.rxjava2 E/ccer: 6----6
01-17 06:01:55.336 5268-5268/com.xiey94.rxjava2 E/ccer: 7----7
01-17 06:01:55.336 5268-5268/com.xiey94.rxjava2 E/ccer: 8----8
01-17 06:01:55.336 5268-5268/com.xiey94.rxjava2 E/ccer: 9----9

buffer

将几个事件合并为一个Observable,这个新的Observable每次发射一组列表值而不是一个一个发射。

Observable
                .fromArray("1", "2", "3", "4", "5", "6", "7", "8")
                .buffer(3)
                .subscribe(new Consumer<List<String>>() {
                    @Override
                    public void accept(List<String> strings) throws Exception {
                        for (String s : strings) {
                            showLog(s);
                        }
                        showLog("---------------分割线----------------");
                    }
                });

打印Log:

01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: 1
01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: 2
01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: 3
01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: ---------------分割线----------------
01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: 4
01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: 5
01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: 6
01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: ---------------分割线----------------
01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: 7
01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: 8
01-17 06:32:22.593 5959-5959/com.xiey94.rxjava2 E/ccer: ---------------分割线----------------

可以看出:上面将3个一组的组合成了多个Observable

Observable
                .fromArray("1", "2", "3", "4", "5", "6", "7", "8")
                .buffer(3, 2)
                .subscribe(new Consumer<List<String>>() {
                    @Override
                    public void accept(List<String> strings) throws Exception {
                        for (String s : strings) {
                            showLog(s);
                        }
                        showLog("---------------分割线----------------");
                    }
                });

多了一个skip参数,将不再按照从头到尾不重复的来,而是每次都跳跃skip的位置开始组合,而不管你的count是多少

打印Log:

01-17 06:34:04.521 6026-6026/? E/ccer: 1
01-17 06:34:04.521 6026-6026/? E/ccer: 2
01-17 06:34:04.521 6026-6026/? E/ccer: 3
01-17 06:34:04.521 6026-6026/? E/ccer: ---------------分割线----------------
01-17 06:34:04.521 6026-6026/? E/ccer: 3
01-17 06:34:04.521 6026-6026/? E/ccer: 4
01-17 06:34:04.521 6026-6026/? E/ccer: 5
01-17 06:34:04.521 6026-6026/? E/ccer: ---------------分割线----------------
01-17 06:34:04.521 6026-6026/? E/ccer: 5
01-17 06:34:04.521 6026-6026/? E/ccer: 6
01-17 06:34:04.521 6026-6026/? E/ccer: 7
01-17 06:34:04.521 6026-6026/? E/ccer: ---------------分割线----------------
01-17 06:34:04.521 6026-6026/? E/ccer: 7
01-17 06:34:04.521 6026-6026/? E/ccer: 8
01-17 06:34:04.521 6026-6026/? E/ccer: ---------------分割线----------------

可以看到:第一个是从1开始,第二个是从1+skip开始,第三个是从1+skip*2开始….

window

window()函数和buffer()很像,但是它发射的是Observable而不是列表。

Observable
                .fromArray("1", "2", "3", "4", "5", "6", "7", "8")
                .window(3)
                .subscribe(stringObservable -> {
                    stringObservable.subscribe(s -> {
                        showLog(s);
                    });
                    showLog("-------------分割线-------------");
                });

打印Log:

01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: 1
01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: 2
01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: 3
01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: 4
01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: 5
01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: 6
01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: 7
01-17 06:41:33.177 6130-6130/com.xiey94.rxjava2 E/ccer: 8

从代码可以看出下游接收到的时候是一个Observable;可能会有疑问,为什么先打印分割线,因为他不是一个同步过程。

一个奇怪的现象:

Observable
                .fromArray("1", "2", "3", "4", "5", "6", "7", "8")
                .window(3, 2)
                .subscribe(stringObservable -> {
                    stringObservable.subscribe(s -> {
                        showLog(s);
                    });
                    showLog("-------------分割线-------------");
                });

打印Log:

01-17 06:57:34.057 6864-6864/? E/ccer: -------------分割线-------------
01-17 06:57:34.057 6864-6864/? E/ccer: 1
01-17 06:57:34.057 6864-6864/? E/ccer: 2
01-17 06:57:34.057 6864-6864/? E/ccer: -------------分割线-------------
01-17 06:57:34.057 6864-6864/? E/ccer: 3
01-17 06:57:34.057 6864-6864/? E/ccer: 3
01-17 06:57:34.057 6864-6864/? E/ccer: 4
01-17 06:57:34.057 6864-6864/? E/ccer: -------------分割线-------------
01-17 06:57:34.057 6864-6864/? E/ccer: 5
01-17 06:57:34.057 6864-6864/? E/ccer: 5
01-17 06:57:34.057 6864-6864/? E/ccer: 6
01-17 06:57:34.057 6864-6864/? E/ccer: -------------分割线-------------
01-17 06:57:34.057 6864-6864/? E/ccer: 7
01-17 06:57:34.057 6864-6864/? E/ccer: 7
01-17 06:57:34.057 6864-6864/? E/ccer: 8

count>skip的时候,就有一些混乱

每三秒收集Observable在此时间内发送的值。组装成Observable发送出去。

Observable
                .interval(1, TimeUnit.SECONDS)
                .window(3, TimeUnit.SECONDS)
                .take(4)
                .subscribe(stringObservable -> {
                    stringObservable.subscribe(s -> {
                        showLog("" + s);
                    });
                    showLog("-------------分割线-------------");
                });

打印Log:

01-17 07:11:27.581 7460-7460/? E/ccer: -------------分割线-------------
01-17 07:11:28.585 7460-7474/com.xiey94.rxjava2 E/ccer: 0
01-17 07:11:29.585 7460-7474/com.xiey94.rxjava2 E/ccer: 1
01-17 07:11:30.585 7460-7474/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 07:11:30.585 7460-7474/com.xiey94.rxjava2 E/ccer: 2
01-17 07:11:31.585 7460-7474/com.xiey94.rxjava2 E/ccer: 3
01-17 07:11:32.585 7460-7474/com.xiey94.rxjava2 E/ccer: 4
01-17 07:11:33.585 7460-7474/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 07:11:33.585 7460-7474/com.xiey94.rxjava2 E/ccer: 5
01-17 07:11:34.585 7460-7474/com.xiey94.rxjava2 E/ccer: 6
01-17 07:11:35.585 7460-7474/com.xiey94.rxjava2 E/ccer: 7
01-17 07:11:36.585 7460-7474/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 07:11:36.585 7460-7474/com.xiey94.rxjava2 E/ccer: 8
01-17 07:11:37.585 7460-7474/com.xiey94.rxjava2 E/ccer: 9
01-17 07:11:38.585 7460-7474/com.xiey94.rxjava2 E/ccer: 10

这个关于时间的我稍稍研究了一下:
一个数据源在不停的发事件,呈现流水线形式,window指定的时间就相当于一个操作工只处理这个指定的时间

看我的代码:

Observable
                .interval(1600, TimeUnit.MILLISECONDS)
                .window(3, TimeUnit.SECONDS)
                .take(4)
                .subscribe(stringObservable -> {
                    stringObservable.subscribe(s -> {
                        showLog("" + s);
                    });
                    showLog("-------------分割线-------------");
                });

打印Log:

01-17 07:37:18.917 7967-7967/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 07:37:20.521 7967-7982/com.xiey94.rxjava2 E/ccer: 0
01-17 07:37:21.921 7967-7982/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 07:37:22.121 7967-7982/com.xiey94.rxjava2 E/ccer: 1
01-17 07:37:23.721 7967-7982/com.xiey94.rxjava2 E/ccer: 2
01-17 07:37:24.921 7967-7982/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 07:37:25.321 7967-7982/com.xiey94.rxjava2 E/ccer: 3
01-17 07:37:26.921 7967-7982/com.xiey94.rxjava2 E/ccer: 4
01-17 07:37:27.921 7967-7982/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 07:37:28.521 7967-7982/com.xiey94.rxjava2 E/ccer: 5
01-17 07:37:30.121 7967-7982/com.xiey94.rxjava2 E/ccer: 6

这个既然是take(4),为什么还有这么多记录,这个因为是4个Observable,而不是事件条数

这里写图片描述

第二个

Observable
                .interval(2500, TimeUnit.MILLISECONDS)
                .window(2, TimeUnit.SECONDS)
                .take(4)
                .subscribe(stringObservable -> {
                    stringObservable.subscribe(s -> {
                        showLog("" + s);
                    });
                    showLog("-------------分割线-------------");
                });

打印Log:

01-17 07:39:51.689 8042-8042/? E/ccer: -------------分割线-------------
01-17 07:39:53.689 8042-8056/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 07:39:54.189 8042-8056/com.xiey94.rxjava2 E/ccer: 0
01-17 07:39:55.689 8042-8056/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 07:39:56.689 8042-8056/com.xiey94.rxjava2 E/ccer: 1
01-17 07:39:57.689 8042-8056/com.xiey94.rxjava2 E/ccer: -------------分割线-------------
01-17 07:39:59.189 8042-8056/com.xiey94.rxjava2 E/ccer: 2

这里写图片描述

看图之后是不是感觉更清楚,清晰了。

scan

相当于一个计算等差/等比数列

一直累加:

Observable
                .just(2, 5, 8)
                .scan((a, b) -> a + b)
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 07:55:52.321 8487-8487/? E/ccer: 2
01-17 07:55:52.325 8487-8487/? E/ccer: 7
01-17 07:55:52.325 8487-8487/? E/ccer: 15

一直累乘:

Observable
                .just(2, 5, 8)
                .scan((a, b) -> a * b)
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 07:56:40.781 8551-8551/com.xiey94.rxjava2 E/ccer: 2
01-17 07:56:40.781 8551-8551/com.xiey94.rxjava2 E/ccer: 10
01-17 07:56:40.781 8551-8551/com.xiey94.rxjava2 E/ccer: 80

还可以添加一个初始值:

累乘:

Observable
                .just(2, 5, 8)
                .scan(5, (a, b) -> a * b)
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 07:58:15.257 8615-8615/com.xiey94.rxjava2 E/ccer: 5
01-17 07:58:15.257 8615-8615/com.xiey94.rxjava2 E/ccer: 10
01-17 07:58:15.261 8615-8615/com.xiey94.rxjava2 E/ccer: 50
01-17 07:58:15.261 8615-8615/com.xiey94.rxjava2 E/ccer: 400

累加:

Observable
                .just(2, 5, 8)
                .scan(5, (a, b) -> a + b)
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 07:59:03.373 8676-8676/com.xiey94.rxjava2 E/ccer: 5
01-17 07:59:03.373 8676-8676/com.xiey94.rxjava2 E/ccer: 7
01-17 07:59:03.373 8676-8676/com.xiey94.rxjava2 E/ccer: 12
01-17 07:59:03.377 8676-8676/com.xiey94.rxjava2 E/ccer: 20

defer

当观察者订阅时,才创建Observable,并且针对每个观察者创建都是一个新的Observable

Observable
                .defer(() -> {
                    showLog("---------------");
                    return Observable.just("A", "B", "C");
                })
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 08:24:16.013 9123-9123/? E/ccer: ---------------
01-17 08:24:16.013 9123-9123/? E/ccer: A
01-17 08:24:16.013 9123-9123/? E/ccer: B
01-17 08:24:16.013 9123-9123/? E/ccer: C

如果不订阅:

Observable
                .defer(() -> {
                    showLog("---------------");
                    return Observable.just("A", "B", "C");
                });

则什么都不打印,从根本上来说就是没创建Observable。

elementAt

从指定的位置索引开始

Observable
                .just("1","2","3")
                .elementAt(1)
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 08:30:31.445 9336-9336/? E/ccer: 2

IgnoreElements

如果不关心一个Observable发射的数据,但是希望在它完成时或遇到错误终止时收到通知

Observable
                .just("1", "2", "3")
                .ignoreElements()
                .subscribe(() -> {
                    showLog("complete");
                });

打印Log:

01-17 08:36:17.641 9536-9536/com.xiey94.rxjava2 E/ccer: complete

takeLast

只发射后面的N项数据

Observable
                .just("1", "2", "3")
                .takeLast(2)
                .subscribe(string -> {
                    showLog(string);
                });

打印Log:

01-17 08:37:52.125 9603-9603/? E/ccer: 2
01-17 08:37:52.125 9603-9603/? E/ccer: 3

说是取最后一段时间内反射的数据,但是打印结果不是很理想:

Observable
                .just("1", "2", "3")
                .takeLast(1, TimeUnit.MICROSECONDS)
                .subscribe(string -> {
                    showLog(string);
                });

takeUntil

发送complete的结束条件 当然发送结束之前也会包括这个值

Observable
                .just(1, 2, 3, 4, 5, 6)
                .takeUntil(integer -> integer >= 3)
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 08:44:53.885 10304-10304/? E/ccer: 1
01-17 08:44:53.885 10304-10304/? E/ccer: 2
01-17 08:44:53.885 10304-10304/? E/ccer: 3

takeWhile

和上面相反

Observable
                .just(1, 2, 3, 4, 5, 6)
                .takeWhile(integer -> integer <= 3)
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 08:46:39.001 10374-10374/? E/ccer: 1
01-17 08:46:39.001 10374-10374/? E/ccer: 2
01-17 08:46:39.001 10374-10374/? E/ccer: 3

skip

丢弃Observable发射的前N项数据

Observable
                .just(1, 2, 3, 4, 5, 6)
                .skip(2)
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 08:47:58.049 10440-10440/com.xiey94.rxjava2 E/ccer: 3
01-17 08:47:58.049 10440-10440/com.xiey94.rxjava2 E/ccer: 4
01-17 08:47:58.049 10440-10440/com.xiey94.rxjava2 E/ccer: 5
01-17 08:47:58.049 10440-10440/com.xiey94.rxjava2 E/ccer: 6

加一个事件参数的:

Observable
                .range(0, 50000)
                .skip(10, TimeUnit.MILLISECONDS)
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 08:51:30.073 10812-10812/? E/ccer: 31591
01-17 08:51:30.073 10812-10812/? E/ccer: 31592
01-17 08:51:30.073 10812-10812/? E/ccer: 31593
01-17 08:51:30.073 10812-10812/? E/ccer: 31594
01-17 08:51:30.073 10812-10812/? E/ccer: 31595
01-17 08:51:30.077 10812-10812/? E/ccer: 31596

...

01-17 08:51:31.153 10812-10812/com.xiey94.rxjava2 E/ccer: 49996
01-17 08:51:31.153 10812-10812/com.xiey94.rxjava2 E/ccer: 49997
01-17 08:51:31.153 10812-10812/com.xiey94.rxjava2 E/ccer: 49998
01-17 08:51:31.153 10812-10812/com.xiey94.rxjava2 E/ccer: 49999

skipLast

一个是丢弃最后的指定数额的事件;
另一个带时间的就是丢弃最后一段指定时间的事件;

distinct

去重

Observable
                .just(1,2,3,3,4,5,6,6,6,7)
                .distinct()
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 08:57:36.257 11023-11023/? E/ccer: 1
01-17 08:57:36.261 11023-11023/? E/ccer: 2
01-17 08:57:36.261 11023-11023/? E/ccer: 3
01-17 08:57:36.261 11023-11023/? E/ccer: 4
01-17 08:57:36.261 11023-11023/? E/ccer: 5
01-17 08:57:36.261 11023-11023/? E/ccer: 6
01-17 08:57:36.261 11023-11023/? E/ccer: 7

注意:发现just中最多放10个item

另一个:这个函数根据原始Observable发射的数据项产生一个Key,然后,比较这些Key而不是数据本身,来判定两个数据是否是不同的

Observable
                .just(1, 2, 3, 3, 4, 5, 6, 6, 6, 7)
                .distinct((Integer Double) -> Math.random())
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 09:05:07.405 11186-11186/? E/ccer: 1
01-17 09:05:07.409 11186-11186/? E/ccer: 2
01-17 09:05:07.409 11186-11186/? E/ccer: 3
01-17 09:05:07.409 11186-11186/? E/ccer: 3
01-17 09:05:07.409 11186-11186/? E/ccer: 4
01-17 09:05:07.409 11186-11186/? E/ccer: 5
01-17 09:05:07.409 11186-11186/? E/ccer: 6
01-17 09:05:07.409 11186-11186/? E/ccer: 6
01-17 09:05:07.409 11186-11186/? E/ccer: 6
01-17 09:05:07.409 11186-11186/? E/ccer: 7

是不是数据不变,因为他们只是数据相同,但是key不同

distinctUntilChanged

(相邻去重):它只判定一个数据和它的直接前驱是 否是不同的,其他概念与distinct一样

和distinct不同的是:distinct是整个列表进行去重,而这个是前后两两去重

Observable
                .just(1, 3, 3, 3, 4, 4, 6, 7, 6, 7)
                .distinctUntilChanged()
                .subscribe(integer -> {
                    showLog("" + integer);
                });

打印Log:

01-17 09:10:12.409 11498-11498/com.xiey94.rxjava2 E/ccer: 1
01-17 09:10:12.409 11498-11498/com.xiey94.rxjava2 E/ccer: 3
01-17 09:10:12.409 11498-11498/com.xiey94.rxjava2 E/ccer: 4
01-17 09:10:12.409 11498-11498/com.xiey94.rxjava2 E/ccer: 6
01-17 09:10:12.409 11498-11498/com.xiey94.rxjava2 E/ccer: 7
01-17 09:10:12.409 11498-11498/com.xiey94.rxjava2 E/ccer: 6
01-17 09:10:12.409 11498-11498/com.xiey94.rxjava2 E/ccer: 7

throttleWithTimeout/debounce

Observable.create(e -> {
            e.onNext("onNext 0");
            Thread.sleep(100);
            e.onNext("onNext 1");
            Thread.sleep(230);
            e.onNext("onNext 2");
            Thread.sleep(300);
            e.onNext("onNext 3");
            Thread.sleep(400);
            e.onNext("onNext 4");
            Thread.sleep(500);
            e.onNext("onNext 5");
            e.onNext("onNext 6");
        })
                .debounce(330, TimeUnit.MILLISECONDS)
//                .throttleWithTimeout(330, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.newThread())
                .observeOn(Schedulers.newThread())
                .subscribe(o -> showLog("" + o));

打印Log:

01-17 09:25:59.321 12134-12151/com.xiey94.rxjava2 E/ccer: onNext 3
01-17 09:25:59.721 12134-12151/com.xiey94.rxjava2 E/ccer: onNext 4
01-17 09:26:00.221 12134-12151/com.xiey94.rxjava2 E/ccer: onNext 6

发送0的时候:然后睡眠了100,就开始了1,100没达到330要求,放弃;
发送1的时候:然后睡眠了230,就开始了2,230没达到330要求,放弃;
发送2的时候:然后睡眠了300,就开始了3,300没达到330要求,放弃;
发送3的时候:然后睡眠了400,就开始了4,330的时候就达到要求了,此后70秒内没有发送事件,所以取第一个事件响应;
发送4的时候:然后睡眠了500,就开始了5,330的时候就达到要求了,此后170秒内没有发送事件,所以取第一个事件响应;
发送5的时候:瞬间就发送6,这两个事件是瞬发的,时间间隔非常短,按理说都应该放弃,但是它保留了最后一个。

ofType

只发射指定类型的数据

Observable.just(1, 2, 3, "str", "B")
                .ofType(String.class)
                .subscribe(s -> showLog(s));

打印Log:

01-17 09:31:51.973 12299-12299/com.xiey94.rxjava2 E/ccer: str
01-17 09:31:51.973 12299-12299/com.xiey94.rxjava2 E/ccer: B

first

只发射第一项

Observable.just(1, 2, 3, "str", "B")
                .first(-1)
                .subscribe(s -> showLog(""+s));

打印Log:

01-17 09:34:22.853 12479-12479/? E/ccer: 1

last

和上面相反,只发射最后一项

merge

根据时间线 合并多个observer

Observable<Long> observable1 = Observable.interval(100, TimeUnit.MILLISECONDS)
                .take(3)
                .subscribeOn(Schedulers.newThread());

        Observable<Long> observable2 = Observable.interval(50, TimeUnit.MILLISECONDS)
                .take(3)
                .map(aLong -> aLong + 10)
                .subscribeOn(Schedulers.newThread());

        Observable.merge(observable1, observable2)
                .subscribe(s -> showLog("" + s));

打印Log:

01-17 09:44:16.697 12706-12722/com.xiey94.rxjava2 E/ccer: 10
01-17 09:44:16.741 12706-12722/com.xiey94.rxjava2 E/ccer: 0
01-17 09:44:16.749 12706-12722/com.xiey94.rxjava2 E/ccer: 11
01-17 09:44:16.797 12706-12722/com.xiey94.rxjava2 E/ccer: 12
01-17 09:44:16.841 12706-12722/com.xiey94.rxjava2 E/ccer: 1
01-17 09:44:16.941 12706-12722/com.xiey94.rxjava2 E/ccer: 2

mergeWith

作用同上

Observable<Long> observable1 = Observable.interval(100, TimeUnit.MILLISECONDS)
                .take(3)
                .subscribeOn(Schedulers.newThread());

        Observable.interval(50, TimeUnit.MILLISECONDS)
                .take(3)
                .map(aLong -> aLong + 10)
                .mergeWith(observable1)
                .subscribe(s -> showLog("" + s));

打印Log:

01-17 09:48:08.697 12796-12810/? E/ccer: 10
01-17 09:48:08.745 12796-12810/? E/ccer: 11
01-17 09:48:08.753 12796-12810/? E/ccer: 0
01-17 09:48:08.797 12796-12810/? E/ccer: 12
01-17 09:48:08.853 12796-12810/? E/ccer: 1
01-17 09:48:08.953 12796-12810/? E/ccer: 2

combineLatest

使用一个函数结合它们最近发射的数据,然后发射这个函数的返回值,它接受二到九个Observable作为参数 或者单 个Observables列表作为参数

Observable<Long> observable1 = Observable.interval(100, TimeUnit.MILLISECONDS)
                .take(4)
                .subscribeOn(Schedulers.newThread());

        Observable<Long> observable2 = Observable.interval(50, TimeUnit.MILLISECONDS)
                .take(3)
                .map(aLong -> aLong + 10);

        Observable.combineLatest(observable1, observable2, (aLong, aLong2) -> {
            showLog("-----------" + aLong + "---------" + aLong2 + "---------");
            return aLong + aLong2;
        }).subscribe(aLong -> showLog("" + aLong));

打印Log:

01-17 10:06:48.969 12973-12992/? E/ccer: -----------0---------11---------
01-17 10:06:48.969 12973-12992/? E/ccer: 11
01-17 10:06:49.013 12973-12992/? E/ccer: -----------0---------12---------
01-17 10:06:49.013 12973-12992/? E/ccer: 12
01-17 10:06:49.073 12973-12992/? E/ccer: -----------1---------12---------
01-17 10:06:49.073 12973-12992/? E/ccer: 13
01-17 10:06:49.169 12973-12992/? E/ccer: -----------2---------12---------
01-17 10:06:49.169 12973-12992/? E/ccer: 14
01-17 10:06:49.269 12973-12992/? E/ccer: -----------3---------12---------
01-17 10:06:49.269 12973-12992/? E/ccer: 15

withLatestFrom

类似zip ,但是只在单个原始Observable发射了一条数据时才发射数据,而不是两个都发;但是注意 如果没有合并元素 既辅助Observable一次都没发射的时候 是不发射数据的

Observable<Long> observable2 = Observable.interval(150, TimeUnit.MILLISECONDS)
                .take(4)
                .subscribeOn(Schedulers.newThread());
        Observable.interval(100, TimeUnit.MILLISECONDS)
                .take(3)
                .subscribeOn(Schedulers.newThread())
                .withLatestFrom(observable2, (aLong, aLong2) -> {
                    System.out.print("aLong:" + aLong + "\t aLong2:" + aLong2 + "\t");
                    return aLong + aLong2;
                })
                .subscribe(o -> System.out.println("===>" + o + "\t"));
日志:
明明原始take是3为啥不是三条log呢 因为原始的发送0的时候 ,辅助Observable还没发送过数据
aLong:1  aLong2:0   ===>1
aLong:2  aLong2:1   ===>3

这个不是很清楚

switchMap

和flatMap类似,不同的是当原始Observable发射一个新的数据(Observable)时,它将取消订阅前一个Observable

Observable.interval(500, TimeUnit.MILLISECONDS)
                .take(3)
                .doOnNext(aLong -> showLog("------doOnNext-----" + aLong))
                .switchMap(aLong -> Observable.intervalRange(aLong * 10, 3, 0, 300, TimeUnit.MILLISECONDS))
                .subscribeOn(Schedulers.newThread())
                .subscribe(aLong -> showLog("" + aLong));

打印Log:

01-18 00:50:42.234 1146-1166/com.xiey94.rxjava2 E/ccer: ------doOnNext-----0
01-18 00:50:42.234 1146-1166/com.xiey94.rxjava2 E/ccer: 0
01-18 00:50:42.534 1146-1166/com.xiey94.rxjava2 E/ccer: 1
01-18 00:50:42.738 1146-1166/com.xiey94.rxjava2 E/ccer: ------doOnNext-----1
01-18 00:50:42.738 1146-1166/com.xiey94.rxjava2 E/ccer: 10
01-18 00:50:43.038 1146-1166/com.xiey94.rxjava2 E/ccer: 11
01-18 00:50:43.238 1146-1166/com.xiey94.rxjava2 E/ccer: ------doOnNext-----2
01-18 00:50:43.238 1146-1166/com.xiey94.rxjava2 E/ccer: 20
01-18 00:50:43.538 1146-1166/com.xiey94.rxjava2 E/ccer: 21
01-18 00:50:43.838 1146-1166/com.xiey94.rxjava2 E/ccer: 22

解析:因为发送2的时候 intervalRange发送第三条数据的时候已经是600ms既 500ms的时候原始数据发送了。导致取消订阅前一个Observable
所以 2 ,12没有发送 但是最后的22发送了 因为原始数据没有新发送的了
// 日志结果
// 0 1
// 10 11
// 20 21 22
// 而不是
// 0 1 2
// 10 11 12
// 20 21 22

这个勉强自己能看懂,但是爱在口心难开。

concat

concat操作符和merge类似,把多个Observable拼接成一个可以观察的输出。

是按照Observable的顺序来的:

Observable observable1 = Observable.range(1, 40000);
        observable1.subscribeOn(Schedulers.newThread());
        Observable observable2 = Observable.just(5, 6, 7, 8);
        observable2.subscribeOn(Schedulers.newThread());
        Observable.concat(observable1, observable2)
                .subscribe((Object o) -> {
                    showLog("" + o);
                });

打印Log:

01-18 01:15:06.098 1499-1499/? E/ccer: 1
01-18 01:15:06.098 1499-1499/? E/ccer: 2
01-18 01:15:06.098 1499-1499/? E/ccer: 3

...

01-18 01:15:07.886 1499-1499/com.xiey94.rxjava2 E/ccer: 39998
01-18 01:15:07.886 1499-1499/com.xiey94.rxjava2 E/ccer: 39999
01-18 01:15:07.886 1499-1499/com.xiey94.rxjava2 E/ccer: 40000
01-18 01:15:07.886 1499-1499/com.xiey94.rxjava2 E/ccer: 5
01-18 01:15:07.886 1499-1499/com.xiey94.rxjava2 E/ccer: 6
01-18 01:15:07.886 1499-1499/com.xiey94.rxjava2 E/ccer: 7
01-18 01:15:07.886 1499-1499/com.xiey94.rxjava2 E/ccer: 8

startWith

是concat()的对应部分,在Observable开始发射他们的数据之前,startWith()通过传递一个参数来先发射一个数据序列

Observable.just("old")
                .startWith("Start")
                .startWith("Start2")
                .startWith(Observable.just("Other Observable"))
                .startWith(Arrays.asList("from Iterable"))
                .startWithArray("from Array", "from Array2")
                .subscribe(s -> showLog(s));

打印Log:

01-18 01:19:56.982 1645-1645/com.xiey94.rxjava2 E/ccer: from Array
01-18 01:19:56.982 1645-1645/com.xiey94.rxjava2 E/ccer: from Array2
01-18 01:19:56.982 1645-1645/com.xiey94.rxjava2 E/ccer: from Iterable
01-18 01:19:56.982 1645-1645/com.xiey94.rxjava2 E/ccer: Other Observable
01-18 01:19:56.982 1645-1645/com.xiey94.rxjava2 E/ccer: Start2
01-18 01:19:56.982 1645-1645/com.xiey94.rxjava2 E/ccer: Start
01-18 01:19:56.982 1645-1645/com.xiey94.rxjava2 E/ccer: old

join

任何时候,只要在另一个Observable发射的数据定义的时间窗口内,这个Observable发射了。一条数据,就结合两个Observable发射的数据

这个不太好理解,我也有点蒙

all

判定是否Observable发射的所有数据都满足某个条件

Observable.just(3, 4, 5, 6)
                .all(integer -> integer < 7)
                .subscribe(aBoolean -> showLog(aBoolean));

打印Log:

01-18 01:50:44.754 1956-1956/? E/ccer: true

ambArray

给定多个Observable,只发射的最后一个

Observable<Integer> observable1 = Observable.range(0, 5);
        Observable<Integer> observable2 = Observable.range(6, 5);

        Observable.ambArray(observable1, observable2)
                .doOnComplete(() -> showLog("complete"))
                .subscribe(integer -> showLog(integer));

打印Log:

01-18 02:02:23.390 2202-2202/? E/ccer: 0
01-18 02:02:23.390 2202-2202/? E/ccer: 1
01-18 02:02:23.390 2202-2202/? E/ccer: 2
01-18 02:02:23.394 2202-2202/? E/ccer: 3
01-18 02:02:23.394 2202-2202/? E/ccer: 4
01-18 02:02:23.394 2202-2202/? E/ccer: complete

contains

判定一个Observable是否发射一个特定的值

Observable.just(1, 2, 3, 4, 5)
                .contains(6)
                .subscribe(aBoolean -> showLog(aBoolean));

打印Log:

01-18 02:05:18.326 2336-2336/? E/ccer: false

switchIfEmpty

如果原始Observable正常终止后仍然没有发射任何数据,就使用备用的Observable

Observable.empty()
                .switchIfEmpty(Observable.range(8, 3))
                .subscribe(o -> showLog(o));

打印Log:

01-18 02:07:38.730 2408-2408/? E/ccer: 8
01-18 02:07:38.730 2408-2408/? E/ccer: 9
01-18 02:07:38.730 2408-2408/? E/ccer: 10

defaultIfEmpty

发射来自原始Observable的值,如果原始Observable没有发射任何值,就发射一个默认值,内部调用的switchIfEmpty。

Observable.empty()
                .defaultIfEmpty(1)
                .subscribe(o -> showLog(o));

打印Log:

01-18 02:09:17.330 2534-2534/? E/ccer: 1

sequenceEqual

判定两个Observables是否发射相同的数据序列。(数据,发射顺序,终止状态)

Observable.sequenceEqual(
                Observable.just(2, 3, 4), Observable.just(2, 3, 4)
        ).subscribe(aBoolean -> showLog(aBoolean));

打印Log:

01-18 02:16:36.198 2913-2913/? E/ccer: true

第三个参数,可以传递一个函数用于比较两个数据项是否相同

Observable.sequenceEqual(
                Observable.just(2, 3, 4)
                , Observable.just(1, 2, 3)
                , ((integer, integer2) -> integer - 1 == integer2)
        ).subscribe(aBoolean -> showLog(aBoolean));

打印Log:

01-18 02:15:37.318 2849-2849/? E/ccer: true

skipUntil

丢弃原始Observable发射的数据,直到第二个Observable发射了一项数据

Observable.intervalRange(30, 20, 500, 100, TimeUnit.MILLISECONDS)
                .skipUntil(Observable.timer(1000, TimeUnit.MILLISECONDS))
                .doOnNext(integer -> showLog(integer))
                .blockingSubscribe();

打印Log:

01-18 02:30:05.506 3320-3334/com.xiey94.rxjava2 E/ccer: 35
01-18 02:30:05.610 3320-3334/com.xiey94.rxjava2 E/ccer: 36
01-18 02:30:05.710 3320-3334/com.xiey94.rxjava2 E/ccer: 37
01-18 02:30:05.810 3320-3334/com.xiey94.rxjava2 E/ccer: 38
01-18 02:30:05.910 3320-3334/com.xiey94.rxjava2 E/ccer: 39
01-18 02:30:06.010 3320-3334/com.xiey94.rxjava2 E/ccer: 40
01-18 02:30:06.110 3320-3334/com.xiey94.rxjava2 E/ccer: 41
01-18 02:30:06.210 3320-3334/com.xiey94.rxjava2 E/ccer: 42
01-18 02:30:06.306 3320-3334/com.xiey94.rxjava2 E/ccer: 43
01-18 02:30:06.410 3320-3334/com.xiey94.rxjava2 E/ccer: 44
01-18 02:30:06.510 3320-3334/com.xiey94.rxjava2 E/ccer: 45
01-18 02:30:06.610 3320-3334/com.xiey94.rxjava2 E/ccer: 46
01-18 02:30:06.710 3320-3334/com.xiey94.rxjava2 E/ccer: 47
01-18 02:30:06.810 3320-3334/com.xiey94.rxjava2 E/ccer: 48
01-18 02:30:06.910 3320-3334/com.xiey94.rxjava2 E/ccer: 49

分析一下:开始是从30开始,走20个,开始延迟了500毫秒没有发射事件,然后每100毫秒发射一个,等到1000毫秒时,已经发射了5个事件了,这时候skipUntil指定的时间是1000毫秒,也就是正好跳过了5个事件,然后发射了第一个,此时我们才接受到第6个事件也就是35

skipWhile

丢弃Observable发射的数据,直到一个指定的条件不成立

Observable.just(1, 2, 3, 4)
                .skipWhile(integer -> integer == 1)
                .doOnNext(integer -> showLog("----------------" + integer))
                .blockingSubscribe();

打印Log:

01-18 02:26:03.890 3106-3106/? E/ccer: ----------------2
01-18 02:26:03.894 3106-3106/? E/ccer: ----------------3
01-18 02:26:03.894 3106-3106/? E/ccer: ----------------4

takeUntil

和skipUntil相反;

当第二个Observable发射了一项数据或者终止时,丢弃原始Observable发射的任何数据

Observable.intervalRange(30, 20, 500, 100, TimeUnit.MILLISECONDS)
                .takeUntil(Observable.timer(1000, TimeUnit.MILLISECONDS))
                .doOnNext(integer -> showLog(integer))
                .blockingSubscribe();

打印Log:

01-18 02:36:04.278 3418-3432/com.xiey94.rxjava2 E/ccer: 30
01-18 02:36:04.378 3418-3432/com.xiey94.rxjava2 E/ccer: 31
01-18 02:36:04.478 3418-3432/com.xiey94.rxjava2 E/ccer: 32
01-18 02:36:04.574 3418-3432/com.xiey94.rxjava2 E/ccer: 33
01-18 02:36:04.678 3418-3432/com.xiey94.rxjava2 E/ccer: 34

takeWhile

发射Observable发射的数据,直到一个指定的条件不成立

Observable.just(2, 3, 4, 5)
                .takeWhile(integer -> integer <= 5)
                .subscribe(integer -> showLog(integer));

打印Log:

01-18 02:41:30.630 3889-3889/? E/ccer: 2
01-18 02:41:30.630 3889-3889/? E/ccer: 3
01-18 02:41:30.630 3889-3889/? E/ccer: 4
01-18 02:41:30.630 3889-3889/? E/ccer: 5

onErrorReturn

让Observable遇到错误时发射一个特殊的项并且正常终止

resumeNext

让Observable在遇到错误时开始发射第二个Observable的数据序列

onErrorResumeNext:可以处理所有的错误

onExceptionResumeNext:只能处理异常

retry

如果原始Observable遇到错误,重新订阅它期望它能正常终止

retryWhen

需要一个Observable 通过判断 throwableObservable,Observable发射一个数据 就重新订阅,发射的是 onError 通知,它就将这个通知传递给观察者然后终

阻塞操作

toList

toSortList

toMap

toFuture

blockingSubscribe

blockingForEach

blockingIterable

blockingFirst

blockingLast

blockingMostRecent

blockingSingle

compose

ConnectableObservable

可连接的Observable在 被订阅时并不开始发射数据,只有在它的connect()被调用时才开始用这种方法,你可以 等所有的潜在订阅者都订阅了这个Observable

replay()

publish(Observable的方法)

将普通的Observable转换为可连接的Observable

timer

Timer会在指定时间后发射一个数字0

Observable.timer(2, TimeUnit.SECONDS).subscribe(aLong -> showLog(aLong));

打印Log:

“`
01-18 03:07:44.670 4579-4593/com.xiey94.rxjava2 E/ccer: 0


未完待续…

参考1:水管
参考2:RxJava2总结之操作详解


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值