RxJava2总结之操作详解(二)

目录

辅助操作

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
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继续订阅取得其组内的值;
  • 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发送出去。
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]
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值