RxJava2总结之操作详解(二)

目录

目录
辅助操作
repeat
repeatUntil
delay
delaySubscription
do系列
doOnEach
doOnNext
doOnSubscribe
doOnComplete
doOnError
doOnTerminate
doFinally
doOnDispose
materialize
dematerialize
observeOn
subscribeOn
subscribe
foreach
serialize
Timestamp
timeInterval
timeout
变换操作
map
flatMap
concatMap
cast
groupBy
window
scan
buffer系列
buffer
辅助操作

repeat

不是创建一个Observable,而是重复发射原始,Observable的数据序列,这个序列或者是无限的,或者通过 repeat(n) 指定重复次数

Observable.just("Love", "For", "You!")
          .repeat(3)//重复三次
          .subscribe(s -> System.out.println(s));
repeatUntil

getAsBoolean 如果返回 true则不repeat false则repeat.主要用于动态控制
Observable.just("Love", "For", "You!")
                .repeatUntil(new BooleanSupplier() {
                    @Override
                    public boolean getAsBoolean() throws Exception {
                        System.out.println("getAsBoolean");
                        count++;
                        if (count == 3)
                            return true;
                        else
                            return false;
                    }
                }).subscribe(s -> System.out.println(s));

delay

延迟一段指定的时间再发射来自Observable的发射物
注意:delay 不会平移 onError 通知,它会立即将这个通知传递给订阅者,同时丢弃任何待 发射的 onNext 通知。然而它会平移一个 onCompleted 通知

Observable.range(0, 3)
          .delay(1400, TimeUnit.MILLISECONDS)
          .subscribe(o -> System.out.println("===>" + o + "\t"));

delaySubscription

让你可以延迟订阅原始Observable

Observable.just(1)
                .delaySubscription(2000, TimeUnit.MILLISECONDS)
                .subscribe(o -> System.out.println("===>" + o + "\t")
                        , throwable -> System.out.println("===>throwable")
                        , () -> System.out.println("===>complete")
                        , disposable -> System.out.println("===>订阅"));

do系列

doOnEach

注册一个回调,它产生的Observable每发射一项数据就会调用它一次

Observable.range(0, 3)
              .doOnEach(integerNotification -> System.out.println(integerNotification.getValue()))
              .subscribe(o -> System.out.print("===>" + o + "\t"));
  日志:
  doOnEach:
  doOnEach:0===>0
  doOnEach:1===>1
  doOnEach:2===>2
  doOnEach:null

doOnNext

注类似doOnEach 不是接受一个 Notification 参数,而是接受发射的数据项。

 Observable.range(0, 3)
         .doOnNext(integer -> {
             if (integer == 2)
                 throw new Error("O__O");
             System.out.print(integer);
         })
         .subscribe(o -> System.out.print("===>" + o + "\t")
                 , throwable -> System.out.print("===>throwable")
                 , () -> System.out.print("===>complete"));
日志:
0===>0  1===>1  ===>throwable

doOnSubscribe

注册一个动作,在观察者订阅时使用

Observable.range(0, 3)
              .doOnSubscribe(disposable -> System.out.print("开始订阅"))
              .subscribe(o -> System.out.print("===>" + o + "\t"));
    日志:
     开始订阅===>0  ===>1   ===>2

doOnComplete

注册一个动作,在观察者OnComplete时使用

Observable.range(0, 3)
               .doOnComplete(() -> System.out.print("doOnComplete"))
               .subscribe(o -> System.out.print("===>" + o + "\t"));
   日志:
    ===>0   ===>1   ===>2   doOnComplete

doOnError

注册一个动作,在观察者doOnError时使用

Observable.error(new Throwable("?"))
               .doOnError(throwable -> System.out.print("throwable"))
               .subscribe(o -> System.out.print("===>" + o + "\t"));
  日志:
  异常信息....
  throwable

doOnTerminate

注册一个动作,Observable终止之前会被调用,无论是正 常还是异常终止。

Observable.range(0, 3)
         .doOnTerminate(() -> System.out.print("\t doOnTerminate"))
         .subscribe(o -> System.out.print("===>" + o + "\t"));
日志:
===>0   ===>1   ===>2        doOnTerminate

doFinally

注册一个动作,当它产生的Observable终止之后会被调用,无论是正常还 是异常终止。在doOnTerminate之后执行

Observable.range(0, 3)
                .doFinally(() -> System.out.print("\t doFinally"))
                .doOnTerminate(() -> System.out.print("\t  doOnTerminate"))
                .subscribe(o -> System.out.print("===>" + o + "\t"));
 日志:
 ===>0  ===>1   ===>2         doOnTerminate  doFinally

doOnDispose

注册一个动作,当【观察者取消】订阅它生成的Observable它就会被调
注意:貌似需要在 为出现complete和error的时候 dispose才会触发 ~

Disposable ab = Observable.interval(1, TimeUnit.SECONDS)
              .take(3)
              .doOnDispose(() -> System.out.println("解除订阅"))
              .subscribe(o -> System.out.print("===>" + o + "\t"));
      ab.dispose();
日志:
解除订阅

materialize

将数据项和事件通知都当做数据项发射

dematerialize

materialize相反

Observable.range(0, 3)
                //将Observable转换成一个通知列表。
                .materialize()
                //与上面的作用相反,将通知逆转回一个Observable
                .dematerialize()
                .subscribe(o -> System.out.print("===>" + o + "\t"));

observeOn

指定一个观察者在哪个调度器上观察这个Observable

subscribeOn

指定Observable自身在哪个调度器上执行
注意 遇到错误 会立即处理而不是等待下游还没观察的数据, 即onError 通知会跳到(并吞掉)原始Observable发射的数据项前面

Observable.range(0, 3)
              .subscribeOn(Schedulers.newThread())
              .observeOn(Schedulers.newThread())
              .subscribe(o -> System.out.print("===>" + o + "\t"));
subscribe

操作来自Observable的发射物和通知

Javadoc: subscribe()
Javadoc: subscribe(onNext)
Javadoc: subscribe(onNext,onError)
Javadoc: subscribe(onNext,onError,onComplete)
Javadoc: subscribe(onNext,onError,onComplete,onSubscribe)
Javadoc: subscribe(Observer)
Javadoc: subscribe(Subscriber)

foreach

forEach 方法是简化版的 subscribe ,你同样可以传递一到三个函数给它,解释和传递给 subscribe 时一样. 
不同的是,你无法使用 forEach 返回的对象取消订阅。也没办法传递一个可以用于取消订阅 的参数

Observable.range(0, 3)
        //subscribe的简化版本  没啥用
        .forEach(o -> System.out.println("===>" + o + "\t"));

serialize

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

Observable.range(0, 3)
           .serialize()
           .subscribe(o -> System.out.print("===>" + o + "\t"));

Timestamp

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

Observable.interval(100, TimeUnit.MILLISECONDS)
               .take(3)
                .timestamp()
                .subscribe(o -> System.out.println("===>" + o + "\t")
                        , throwable -> System.out.println("===> throwable")
                        , () -> System.out.println("===> complete")
                        , disposable -> System.out.println("===> 订阅"));
    日志:
    ===> 订阅
    ===>Timed[time=1501224256554, unit=MILLISECONDS, value=0]
    ===>Timed[time=1501224256651, unit=MILLISECONDS, value=1]
    ===>Timed[time=1501224256751, unit=MILLISECONDS, value=2]
    ===> complete

timeInterval

一个发射数据的Observable转换为发射那些数据发射时间间隔的Observable
1
Observable.interval(100, TimeUnit.MILLISECONDS)
                .take(3)
//         把发送的数据 转化为  相邻发送数据的时间间隔实体
                .timeInterval()
//                .timeInterval(Schedulers.newThread())
                .subscribe(o -> System.out.println("===>" + o + "\t")
                        , throwable -> System.out.println("===>throwable")
                        , () -> System.out.println("===>complete")
                        , disposable -> System.out.println("===>订阅"));
    日志:
    ===>订阅
    ===>Timed[time=113, unit=MILLISECONDS, value=0]
    ===>Timed[time=102, unit=MILLISECONDS, value=1]
    ===>Timed[time=97, unit=MILLISECONDS, value=2]
    ===>complete

timeout

变体:过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),它会发一个错误
Observable.interval(100, TimeUnit.MILLISECONDS)
//        过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),它会发一个错误
                .timeout(50, TimeUnit.MILLISECONDS)
                .subscribe(o -> System.out.println("===>" + o + "\t")
                        , throwable -> System.out.println("===>timeout throwable")
                        , () -> System.out.println("===>timeout complete")
                        , disposable -> System.out.println("===>timeout 订阅"));
timeout:
===>timeout 订阅
===>timeout throwable

变体 备用Observable:过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),它会发一个错误
Observable<Integer> other;
Observable.empty()
         // 过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),他会用备用Observable 发送数据,本身的会发送一个compelte
         .timeout(50, TimeUnit.MILLISECONDS, other = Observable.just(2, 3, 4))
         .subscribe(o -> System.out.println("===>" + o + "\t")
                 , throwable -> System.out.println("===>timeout2 throwable")
                 , () -> System.out.println("===>timeout2 complete")
                 , disposable -> System.out.println("===>timeout2 订阅"));
 other.subscribe(o -> System.out.println("k ===>" + o + "\t"));
timeout2:
===>timeout2 订阅
===>timeout2 complete
k ===>2
k ===>3
k ===>4

变换操作

map

对Observable发射的每一项数据应用一个函数,执行变换操作,就是方形过渡到圆形

Observable.just(1,2)
              .map(integer -> "This is result " + integer)
              .subscribe(s -> System.out.println(s));

flatMap

将一个发射数据的Observable变换为多个Observables,然后将它们发射的数据合并后放进一个单独的Observable

mapper:根据发射数据映射成Observable
combiner: 用来合并 的
注意:FlatMap 对这些Observables发射的数据做的是合并( merge )操作,因此它们可能是交 错的。

Observable.just(1, 2, 3)
        .flatMap(integer -> Observable.range(integer * 10, 2)
        , (a, b) -> {
                           //a : 原始数据的 just(1,2,3) 中的值
                           //b : 代表 flatMap后合并发送的数据的值
                           System.out.print("\n a:" + a + "\t b:" + b);
                           //return flatMap发送的值 ,经过处理后 而发送的值
                           return a + b;
                       })
               .subscribe(s -> System.out.print("\t"+s));
日志:
 <!-- 这里有顺序是因为没有在其他线程执行 -->
a:1  b:10   11
a:1  b:11   12
a:2  b:20   22
a:2  b:21   23
a:3  b:30   33
a:3  b:31   34

concatMap

类似FlatMap但是保证顺序 因为没有合并操作!

Observable.just(1, 2, 3)
            .concatMap(integer -> Observable.range(integer * 10, 2))
            .subscribe(s -> System.out.print("\t"+s));

cast

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

Observable.just(1, 2, "string")
               .cast(Integer.class)//订阅之后才能发横强转
               .subscribe(integer -> System.out.println(integer)
                       , throwable -> System.out.println(throwable.getMessage()));

groupBy

通过keySelector的apply的值当做key 进行分组,发射GroupedObservable(有getKey()方法)的group 通过group继续订阅取得其组内的值;
1
keySelector:通过这个的返回值 当做key进行分组
valueSelector:value转换
Observable.range(0, 10)
                .groupBy(integer -> integer % 2, integer -> "(" + integer + ")")
                .subscribe(group -> {
                    group.subscribe(integer -> System.out.println(
                            "key:" + group.getKey() + "==>value:" + integer));
                });
日志:
key:0==>value:(0)
key:1==>value:(1)
key:0==>value:(2)
key:1==>value:(3)
key:0==>value:(4)
key:1==>value:(5)
key:0==>value:(6)
key:1==>value:(7)
key:0==>value:(8)
key:1==>value:(9)

window

依照此范例 每三秒收集,Observable在此时间内发送的值。组装成Observable发送出去。
1
Observable.interval(1, TimeUnit.SECONDS).take(7)
                //返回值  Observable<Observable<T>> 即代表 发送Observable<T>
                .window(3, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .subscribe(integerObservable -> {
                    System.out.println(integerObservable);
                    integerObservable.subscribe(integer -> System.out.println(integerObservable+"===>"+integer));
                });
日志:
为什么不是 345一起? 因为会有太细微的时间差。例如5如果在多线程切换的时候是超过3秒的1毫秒则就尴尬了~
io.reactivex.subjects.UnicastSubject@531c3d1c
io.reactivex.subjects.UnicastSubject@531c3d1c===>0
io.reactivex.subjects.UnicastSubject@531c3d1c===>1
io.reactivex.subjects.UnicastSubject@531c3d1c===>2
io.reactivex.subjects.UnicastSubject@2ea0f969
io.reactivex.subjects.UnicastSubject@2ea0f969===>3
io.reactivex.subjects.UnicastSubject@2ea0f969===>4
io.reactivex.subjects.UnicastSubject@2d30de03
io.reactivex.subjects.UnicastSubject@2d30de03===>5
io.reactivex.subjects.UnicastSubject@2d30de03===>6

scan

连续地对数据序列的每一项应用一个函数,然后连续发射结果

感觉就是发送一个有 累加(函数) 过程序列 
* initialValue(可选) 其实就是放到 原始数据之前发射。 
* a 原始数据的中的值 
* b 则是最后应用scan函数后发送的值

Observable.just(1, 4, 2)
                //7是用来 对于第一次的 a的值
                .scan(7, (a, b) -> {
                    //b 原始数据的 just(1,4,2) 中的值
                    //a 则是最后应用scan 发送的值
                    System.out.format("a:%d * b:%d\n", a, b);
                    return a * b;
                })
                .subscribe(integer -> System.out.println("===>:"+integer));
日志:
===>:7
a:7 * b:1
===>:7
a:7 * b:4
===>:28
a:28 * b:2
===>:56

buffer系列

buffer

变体 count系列
 1. 范例:发射[1-10]
 2. buffer count 2 skip 1,结果 [1,2]  [2,3] [3,4] 3=2*1+1
 3. buffer count 2 skip 2,结果 [1,2]  [3,4] [5,6] 5=2*2+1
 4. buffer count 2 skip 3,结果 [1,2]  [4,5] [7,8] 7=2*3+1;

1) count:缓存的数量 
2) skip:每个缓存创建的间隔数量 
这代表 每次初始偏移量 每次真正的起始值=fistValue+skip*skipCount; 
注意skip不能小于0 
可以小于count这样就会导致每个发送的list之间的值会有重复 
可以大于count这样就会导致每个发送的list之间的值和原有的值之间会有遗漏 
可以等于count就你懂的了 
3) bufferSupplier:自定义缓存装载的容器

Observable.range(1, 10)
        .buffer(2, 1,() -> new ArrayList<>())//有默认的装载器
        <!-- 其他方法 -->
        <!-- .buffer(2)//skip 默认和count一样 -->
        <!--  .buffer(2, () -> new ArrayList<>())-->
        .subscribe(integers -> System.out.println(integers));
 解析:每发射1个。创建一个发射物list buffer,每个buffer缓存2个,收集的存入list后发送。

变体 time系列
1) timespan:缓存的时间 
2) timeskip:每个缓存创建的间隔时间 同skip 可以小于大于等于timespan

Observable.interval(500, TimeUnit.MILLISECONDS).take(7)
                .buffer(3, 2, TimeUnit.SECONDS, Schedulers.single(),
                        Functions.createArrayList(16))
                .subscribe(integers -> System.out.println(integers));
解析:每两秒创建一个发射物list buffer,每个buffer缓存三秒 收集的存入list后发送。
日志:
  [0, 1, 2, 3, 4]
  [4, 5, 6]

3) 变体 自定义buffer创建和收集时间 
4) bufferOpenings:每当 bufferOpenings 发射了一个数据时,它就 创建一个新的 List,开始装入之后的发射数据 
5) closingSelector:每当 closingSelector 发射了一个数据时,就结束装填数据 发射List。

 <!-- 范例和time系列的就一样了 -->
 Consumer<Long> longConsumer = aLong -> System.out.println("开始创建 bufferSupplier");
        Consumer<Long> longConsumer2 = aLong -> System.out.println("结束收集");
        Observable.interval(500, TimeUnit.MILLISECONDS).take(7)
//                .doOnNext(aLong -> System.out.println("原始发射物:" + aLong))
                .buffer(Observable.interval(2, TimeUnit.SECONDS)
                                .startWith(-1L)//为了刚开始就发射一次
                                .take(2)//多余的我就不创建了
                                .doOnNext(longConsumer)
                        , aLong -> Observable.timer(3, TimeUnit.SECONDS)
                                .doOnNext(longConsumer2)
                        , () -> new ArrayList<>())
                .subscribe(integers -> System.out.println("buffer发射物" + integers));
日志:
openings:
开始创建 bufferSupplier
开始创建 bufferSupplier
结束收集
buffer发射物[0, 1, 2, 3, 4]
buffer发射物[4, 5, 6]

变体 仅仅bufer创建时间
boundarySupplier 因为发送一个值代表上个缓存的发送 和这个缓存的创建 
*注释: 这个缓存是连续的, 因为发送一个值代表上个缓存的发送 和这个缓存的创建 
有发射物的时候 没缓存就创建了 就是 默认第一个发射物的时候由内部创建 
注意 如果不发送事件缓存 存满了 会自动发送出去的

Observable.interval(500, TimeUnit.MILLISECONDS).take(7)
                .buffer(() -> Observable.timer(2, TimeUnit.SECONDS)
                                .doOnNext(aLong -> System.out.println("开始创建 bufferSupplier"))
                        , () -> new ArrayList<Object>())
                .subscribe(integers -> System.out.println(integers));
日志:
开始创建 bufferSupplier
[0, 1, 2]
[3, 4, 5, 6]
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值