Quantcast
Viewing all articles
Browse latest Browse all 5930

RxJava之辅助操作符

Observable的创建源于数据源,如何从Observable转换回数据源呢?观察者订阅后,如何推迟Observable发射数据呢?观察者订阅后,在Observable调用观察者的方法前,做一些其他的事情又该如何做呢?…带着思考的问题,让我们看下辅助操作符带给我们的无限遐想!

delay

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

delay操作符让原Observable在发射每项数据之前都暂停一段指定的时间段,其效果是Observable发射的数据项在时间上向前整体平移了一个增量。

在RxJava中,通过delay()和delaySubscription()实现delay.

在RxJava中,delay()操作符有很多变体,下面一一介绍其变体:
Image may be NSFW.
Clik here to view.
这里写图片描述

delay(long,TimeUnit)和delay(long,TimeUnit, scheduler)变体接受一个定义时长的参数(包括时长和时间单位)。每当原Observable发射一项数据,delay就启动一个定时器,当定时器过了给定的时间段时,delay创建并返回一个Observable,其与原Observable发射相同的数据项。

delay(long,TimeUnit)和delay(long,TimeUnit, scheduler)默认在computation调度器上执行,可以通过参数指定使用其它的调度器。
Image may be NSFW.
Clik here to view.
这里写图片描述

delay(Func1))变体不采用时间参数,而是接受一个函数参数,针对原Observable发射的数据,创建并返回一个Observable,暂且命名为_Observable,同时订阅这个_Observable。当任何一个_Observable终止时,delay()返回的_Observable就发射与其关联的那项数据。该变体默认不在任何特定的调度器上执行。
Image may be NSFW.
Clik here to view.
这里写图片描述

delay(Func0,Func1)变体接收两个函数参数,Func0函数对每一项数据使用一个Observable作为原始Observable的延时定时器。

API

Javadoc: delay(Func1)
Javadoc: delay(Func0,Func1)
Javadoc: delay(long,TimeUnit)
Javadoc: delay(long,TimeUnit, scheduler)

示例代码

1.delay(long,TimeUnit)

Observable.create(new Observable.OnSubscribe<Student>() {
    @Override
    public void call(Subscriber<? super Student> subscriber) {
        Log.i(TAG, "call:" + String.valueOf(SystemClock.uptimeMillis()));
        subscriber.onNext(getListOfStudent().get(0));
        Log.i(TAG, "call:" + String.valueOf(SystemClock.uptimeMillis()));
        subscriber.onNext(getListOfStudent().get(1));
        Log.i(TAG, "call:" + String.valueOf(SystemClock.uptimeMillis()));
        subscriber.onNext(getListOfStudent().get(2));
    }
}).delay(1, TimeUnit.SECONDS)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<Student>() {

            @Override
            public void onStart() {
                super.onStart();
                mAdaStudent.clear();

                Log.i(TAG, "onStart:" + String.valueOf(SystemClock.uptimeMillis()));
            }

            @Override
            public void onCompleted() {
                Log.i(TAG, "do onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "do onError");
            }

            @Override
            public void onNext(Student student) {
                Log.i(TAG, "do onNext");
                Log.i(TAG, "onNext:" + String.valueOf(SystemClock.uptimeMillis()));
                mAdaStudent.addData(student);
            }
        });

2.

  ****
 .delay(new Func1<Student, Observable<Student>>() {
        @Override
        public Observable<Student> call(Student student) {
            return Observable.timer(2, TimeUnit.SECONDS)
                    .flatMap(new Func1<Long, Observable<Student>>() {
                        @Override
                        public Observable<Student> call(Long aLong) {
                            return Observable.just(student);
                        }
                    });
        }
    })

    ***

Log打印

1.delay(long,TimeUnit)
onStart:680479501
call:680479502
call:680479502
call:680479503
do onNext
onNext:680480503
do onNext
onNext:680480505
do onNext
onNext:680480506
2.delay(Func1)
onStart:681525874
call:680479512
call:681525914
call:681525916
do onNext
onNext:681527964
do onNext
onNext:681527966
do onNext
onNext:681527966

示例解析

1.通过delay(1,TimeUnit.Seconds),将原Observable发射数据时间推迟1秒。从Log打印看出,call:xxx与onNext:XXX时间相比相差1000毫秒左右,意味着观察者比原Observable发射的数据时间相差1S,与之前设定的时间延迟一致。
2.从示例代码2中可以看出,delay(Func1),创建一个新的_Observable,此_Observable需与原Obsevable发射的数据相关联。_Observable设置了延迟两秒发射,_Observable终止时,发射与其相关联的数据。从Log打印看出,call:xxx与onNext:XXX时间相比相差2000毫秒左右.

do

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

do操作符作为注册一个动作作为原Observable生命周期事件的一种占位符

在RxJava中实现了很多do操作符的变体,下面一一介绍:
Image may be NSFW.
Clik here to view.
这里写图片描述

doOnEach操作符可注册一个回调,它产生的Observable每发射一项数据就会调用它一次。可以以Action的形式传递参数给它,这个Action接受一个onNext的变体Notification作为它的唯一参数,也可以传递一个Observable给doOnEach,这个Observable的onNext会被调用,就好像它订阅了原Observable一样。
Image may be NSFW.
Clik here to view.
这里写图片描述

doOnNext操作符类似于doOnEach(Action1),但是它的Action不是接受一个Notification参数,而是接受发射的数据项。
Image may be NSFW.
Clik here to view.
这里写图片描述

doOnSubscribe操作符注册一个动作,当观察者订阅它生成的Observable它就会被调用。
Image may be NSFW.
Clik here to view.
这里写图片描述

doOnUnsubscribe操作符注册一个动作,当观察者取消订阅它生成的Observable它就会被调用。
Image may be NSFW.
Clik here to view.
这里写图片描述

doOnCompleted 操作符注册一个动作,当它产生的Observable正常终止调用onCompleted时会被调用。
Image may be NSFW.
Clik here to view.
这里写图片描述

doOnError 操作符注册一个动作,当它产生的Observable异常终止调用onError时会被调用。
Image may be NSFW.
Clik here to view.
这里写图片描述

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

API

Javadoc: doOnEach(Action1)
Javadoc: doOnEach(Observer)

Javadoc: doOnNext(Action1)

Javadoc: doOnSubscribe(Action0))

Javadoc: doOnUnsubscribe(Action0)

Javadoc: doOnError(Action0)

Javadoc: doOnTerminate(Action0)

示例代码

1.正常执行,无onError通知

Observable.just(new Student(1, "create - 1", 20), new Student(1, "create - 1", 20))
        .subscribeOn(Schedulers.io())
        .doOnEach(new Action1<Notification<? super Student>>() {
            @Override
            public void call(Notification<? super Student> notification) {
                Log.i(TAG, "doOnEach");
            }
        })

        .doOnNext(new Action1<Student>() {
            @Override
            public void call(Student student) {
                Log.i(TAG, "doOnNext");
            }
        })
        .doOnSubscribe(new Action0() {
            @Override
            public void call() {
                Log.i(TAG, "doOnSubscribe");
            }
        })
        .doOnUnsubscribe(new Action0() {
            @Override
            public void call() {
                Log.i(TAG, "doOnUnsubscribe");
            }
        })
        .doOnError(new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                Log.i(TAG, "doOnError");
            }
        })

        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<Student>() {

            @Override
            public void onStart() {
                super.onStart();
                Log.i(TAG, "onStart");
            }

            @Override
            public void onCompleted() {
                Log.i(TAG, "onCompleted");

            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError");
            }

            @Override
            public void onNext(Student student) {
                Log.i(TAG, "onNext");
                Log.i(TAG, "onNext - student:" + student.toString());
                mAdaStudent.addData(student);
                //unsubscribe();
            }
        }); 

2.有onError通知

Observable.create(new Observable.OnSubscribe<Student>() {
    @Override
    public void call(Subscriber<? super Student> subscriber) {
        subscriber.onNext(new Student(1001, "do - 1", 20));
        subscriber.onError(new Throwable("do"));
    }
})***

Log打印

1.
doOnSubscribe

doOnEach
doOnNext
onNext
onNext - student:Student{id='1'name='create - 1', age=20}

doOnEach
doOnNext
doOnEach
onNext
onNext - student:Student{id='1'name='create - 1', age=20}

onCompleted
doOnUnsubscribe

2.有onError通知
onStart
doOnSubscribe

doOnNext

doOnError
doOnError

doOnUnsubscribe

示例解析

Image may be NSFW.
Clik here to view.
这里写图片描述

细看上面流程图,可以了解到各个do变体在Observable整个声明周期中执行过程。
但是对于doOnCompleted和doOnTerminate只是针对于设定的Observable的生命周期相关联,假如设置应采用就近原则,意味着其与临着最近的Observable的生命周期相关联。

materialize

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

materialize操作符操作符将原Observable的onNext和终止通知onCompleted或onError都转换为一个Observable发射的Notification对象的序列。而一个合法的有限的Obversable将调用它的观察者的onNext方法零次或多次,然后调用观察者的onCompleted或onError正好一次。

materialize默认不在任何特定的调度器 (Scheduler) 上执行。

API

Javadoc: materialize()

dematerialize

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

dematerialize操作符是materialize操作符的逆向过程,将原Observable发射的Notification对象还原成Observable的通知。

dematerialize默认不在任何特定的调度器 (Scheduler) 上执行。

API

Javadoc: dematerialize()

observeOn

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

observeOn操作符指定Observable在一个特定的调度器上发送通知给观察者 (调用观察者的onNext, onCompleted, onError方法)。
Image may be NSFW.
Clik here to view.
这里写图片描述

当遇到一个异常时ObserveOn会立即向前传递这个onError终止通知,它不会等待Observable接受任何之前它已经收到但还没有发射的数据项。这可能意味着onError通知会跳到(并丢弃)原Observable发射的数据项前面,正如图例上展示的。

API

Javadoc: observeOn(Scheduler)

subscribeOn

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

SubscribeOn操作符指定Observable在一个特定的调度器上运转。

API

Javadoc: subscribeOn(Scheduler))
Javadoc: unsubscribeOn(Scheduler))

serialize

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

一个Observable可以异步调用它的观察者的方法,可能是从不同的线程调用。这样会让Observable调用冲突,它可能会在某一个onNext调用之前尝试调用onCompleted或onError方法,或者从两个不同的线程同时调用onNext方法。使用Serialize操作符,你可以纠正这个Observable的行为,保证它的行为是正确的且是同步的。

serialize操作符默认不在任何特定的调度器上执行。

API

Javadoc: serialize())

subscribe

概述

subscribe操作符连接观察者和Observable的桥梁。一个观察者要想接收到Observable发射的数据项,或者想要从Observable接收错误和完成通知,它首先必须使用该操作符订阅Observable。

Subscribe操作符的参数是Subscriber一般实现可能会接受一到三个方法(然后由观察者组合它们),或者接受一个实现了包含这三个方法的接口的对象(有时叫做Observer或Subscriber).

subscribe方法返回一个实现了Subscription接口的对象。这个接口包含unsubscribe和isSubscribe方法,任何时刻你都可以调用unsubscribe()方法来取消观察者订阅Observable,同时可以调用isSubscribe判断该观察者是否已订阅该Observable。

API

Javadoc: subscribe()
Javadoc: subscribe(Action1))
Javadoc: subscribe(Action1,Action1)
Javadoc: subscribe(Action1,Action1,Action0)
Javadoc: subscribe(Observer)
Javadoc: subscribe(Subscriber)

timeInterval

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

timeInterval操作符将拦截原Observable发射的数据项,替换为发射表示相邻发射物时间间隔的对象。但,未创建与原Observable发射最后一项数据和发射onCompleted通知之间时长对应的时间间隔的对象。

timeInterval默认在immediate调度器上执行,但可通过传参数指定执行的调度器。

API

Javadoc: timeInterval()
Javadoc: timeInterval(Scheduler)

timeout

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

timeout操作符在原Observable了指定的一段时长没有发射任何数据时,将会发送一个onError通知终止这个Observable。

在RxJava中有很多timeout操作符的变体,以满足各种情况下的需求。下面一一描述:
Image may be NSFW.
Clik here to view.
这里写图片描述

timeout(long,TimeUnit)变体接受时间参数和时间单位参数,来设定间隔时长,每当原Observable发射了一项数据,timeout就启动一个计时器,如果计时器超过了指定指定的时长而原Observable没有发射另一项数据,timeout就抛出TimeoutException,以一个错误通知终止Observable。
Image may be NSFW.
Clik here to view.
这里写图片描述

timeout(long,TimeUnit,Observable)和timeout(long,TimeUnit,Observable,Scheduler)变体不会发送错误通知终止,而是重新订阅备用的Observable并发射其数据项。她们默认在computation调度器上执行,而timeout(long,TimeUnit,Observable,Scheduler)变体可以通过Scheduler参数指定执行调度器。
Image may be NSFW.
Clik here to view.
这里写图片描述

timeout(Func1)变体在原Observable发送一个数据时,不是启动一个计时器,而是创建并返回一个_Observable,若_Observable终止时,原Observable还没有发送数据,timeout就抛出TimeoutException,以一个错误通知终止Observable。该变体默认在immediate调度器上执行。
Image may be NSFW.
Clik here to view.
这里写图片描述

timeout(Func0,Func1)变体类似于timeout(Func1),不同的是不会发送错误通知终止,而是重新订阅备用的Observable并发射其数据项。该变体默认在immediate调度器上执行。

API

Javadoc: timeout(long,TimeUnit)

Javadoc: timeout(long,TimeUnit,Observable)
Javadoc: timeout(long,TimeUnit,Observable,Scheduler)

Javadoc: timeout(Func1))

Javadoc: timeout(Func0,Func1))

示例代码

Observable.interval(2, TimeUnit.SECONDS)
        .timeout(1, TimeUnit.SECONDS, Observable.just(new Long(-1)))
        .subscribeOn(Schedulers.io())
        .flatMap(aLong -> {
            if (aLong == -1) {
                return Observable.just(new Student(1, new String("timeout - 1"), 20));
            }
            return Observable.just(new Student(aLong.intValue(), new String("timeout - 1"), 20));
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(student -> {
            mAdaStudent.addData(student);
            Log.i(TAG, student.toString());
        });

Log打印

Student{id='1'name='timeout - 1', age=20}

示例解析

看示例代码,创建了一个每隔2秒发送一个long类型的Observable,但其将timeout(long,TimeUnit,Observable)变体设置间隔时间为1s,同时设定备用Observable为Observable.just(new Long(-1)).使用flapmap操作符转换为Obeservable。根据上述设定,Observable明显会超时,发送onError通知。但是通过Log打印可以看出,onError通知被拦截,而是使用了备用的Observable发射数据。

timestamp

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

timestamp操作符将原Observable发射的T类型数据的转换为一个发射类型为Timestamped的数据的Observable,每一项都包含数据的原始发射时间,同时将其发射出去。

该操作符默认在immediate调度器上执行,但是可以通过参数指定其它的调度器。

API

Javadoc: timestamp())
Javadoc: timestamp(Scheduler))

示例代码

Observable.from(getListOfStudent())
            .subscribeOn(Schedulers.io())
            .take(2)
            .timestamp()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<Timestamped<Student>>() {
                @Override
                public void call(Timestamped<Student> stu) {
                    Log.i(TAG, stu.toString());
                }
            });

Log打印

Timestamped(timestampMillis = 1473076584097, value = Student{id='1'name='A', age=23})
Timestamped(timestampMillis = 1473076584098, value = Student{id='2'name='B', age=33})

示例解析

示例中,截取了Observable的前两个数据用来发射,同时使用timestamp操作符将发射的每个数据增加时间戳,在订阅时,参数的数据类型的泛型为Timestamped。看Log打印,Timestamped的成员中,timestampMillis为时间戳,而value为原Observable发射的数据。

using

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

using操作符让你可以指示Observable创建一个只在它的生命周期内存在的资源,当Observable终止时这个资源会被自动释放。

using操作符接受三个参数:

  • 一个用户创建一次性资源的工厂函数
  • 一个用于创建Observable的工厂函数
  • 一个用于释放资源的函数

当一个观察者订阅using返回的Observable时,using将会使用Observable工厂函数创建观察者要观察的Observable,同时使用资源工厂函数创建一个你想要创建的资源。当观察者取消订阅这个Observable时,或者当观察者终止时(无论是正常终止还是因错误而终止),using使用第三个函数释放它创建的资源。

该操作符默认不在任何特定的调度器上执行。

API

Javadoc: using(Func0,Func1,Action1))

示例代码

Observable.from(getListOfStudent())
        .subscribeOn(Schedulers.io())
        .using(new Func0<Integer>() {
            @Override
            public Integer call() {
                return new Random().nextInt(10);
            }
        }, new Func1<Integer, Observable<Student>>() {
            @Override
            public Observable<Student> call(Integer integer) {
                return Observable.just(new Student(integer, "using -  " + integer, 20 + integer));
            }
        }, new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                integer = null;
            }
        }).observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<Student>() {
            @Override
            public void call(Student stu) {
                Log.i(TAG, stu.toString());
                mAdaStudent.addData(stu);
            }
        });

Log打印

Student{id='4'name='using -  4', age=24}

示例解析

示例中,Observable.from(getListOfStudent())创建了一个Observable对象,理论上应该打印getListOfStudent()获取的student列表,但是使用using操作符创建了一个在原Observable生命周期内的一次性资源,同时使用资源创建了新的Observable,暂时称为_observable.现看Log打印,只是打印了_observable发射的数据,意味着观察者订阅原Observable后,并未收到原Observable发射的数据,应该是丢弃了,只是收到了_observable发射的数据。

to

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

to操作符将Observable转换为另一个对象或数据结构的Observable。

在RxJava实现中,to操作符可以将Observable或者Observable发射的数据序列转换为另一个对象或数据结构,它们中的一些会阻塞直到Observable终止,然后生成一个等价的对象或数据结构;另一些返回一个发射那个对象或数据结构的Observable。为满足各种情况需求,to操作符有多种变体,例如getIterator、toFuture、toIterable、toList、toMap、toMultiMap、toSortedList。

getIterator

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

getIterator操作符只能用于BlockingObservable的子类,如果要使用该操作符,首先必须把原Observable转换为一个BlockingObservable。可以BlockingObservable.from或the Observable.toBlocking使用这两个操作符进行转换。

该操作符将Observable转换为一个Iterator,可以通过它迭代原始Observable发射的数据集。

API

Javadoc: BlockingObservable.getIterator()

示例代码

Iterator<Student> iterator  = Observable.from(getListOfStudent())
        .subscribeOn(Schedulers.io())
        .toBlocking()
        .getIterator();

while (iterator.hasNext()) {
    Log.i(TAG, iterator.next().toString());
}

Log打印

Student{id='1'name='A', age=23} 
Student{id='2'name='B', age=33} 
Student{id='3'name='C', age=24} 
Student{id='4'name='D', age=24} 
Student{id='5'name='E', age=33} 
Student{id='6'name='F', age=23} 

示例解析

示例中,创建了Observable对象,使用操作符.toBlocking将原Observable转换为BlockingObservable,因为getIterator操作符只能用于BlockingObservable的子类。然后使用getIterator(),将原Observable转换为数据的集合,最后将集合遍历,遍历结果见Log打印。

toFuture

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

toFuture操作符类似于getIterator操作符,也只能用于BlockingObservable。该操作符将Observable转换为一个返回单个数据项的Future,如果原Observable发射多个数据项,Future会收到一个IllegalArgumentException异常;如果原Observable没有发射任何数据,Future会收到一个NoSuchElementException异常。

如果想将发射多个数据项的Observable转换为Future,可以这样用:myObservable.toList().toBlocking().toFuture()。

API

示例代码

try {
    Future<List<Student>> future = Observable.from(getListOfStudent())
            .subscribeOn(Schedulers.io())
            .toList()
            .toBlocking()
            .toFuture();
    Log.i(TAG, future.get().toString());
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
    }

Log打印

 [Student{id='1'name='A', age=23},
  Student{id='2'name='B', age=33}, 
  Student{id='3'name='C', age=24}, 
  Student{id='4'name='D', age=24}, 
  Student{id='5'name='E', age=33}, 
  Student{id='6'name='F', age=23}]

toIterable

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

toIterable操作符只能用于BlockingObservable。该操作符将Observable转换为一个Iterable,可以通过它迭代原Observable发射的数据集。

API

Javadoc: BlockingObservable.toIterable()

示例代码

Iterable<Student> iterable= Observable.from(getListOfStudent())
        .subscribeOn(Schedulers.io())
        .toBlocking()
        .toIterable();

for (Student stu : iterable) {
    Log.i(TAG, stu.toString());
}

Log打印

Student{id='1'name='A', age=23} 
Student{id='2'name='B', age=33} 
Student{id='3'name='C', age=24} 
Student{id='4'name='D', age=24} 
Student{id='5'name='E', age=33} 
Student{id='6'name='F', age=23} 

toList

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

toList操作符将发射多项数据且为每一项数据调用onNext方法的Observable发射的多项数据组合成一个List,然后调用一次onNext方法传递整个列表。

如果原Observable没有发射任何数据就调用了onCompleted,toList返回的Observable会在调用onCompleted之前发射一个空列表。如果原Observable调用了onError,toList返回的Observable会立即调用它的观察者的onError方法。

toList默认不在任何特定的调度器上执行。

API

Javadoc: toList()

示例代码

Observable.from(getListOfStudent())
        .subscribeOn(Schedulers.io())
        .toList()
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<List<Student>>() {

            @Override
            public void onStart() {
                super.onStart();
                mAdaStudent.clear();
            }

            @Override
            public void onCompleted() {
                mCompositeSubscription.remove(this);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(List<Student> stus) {
                mAdaStudent.addData(stus);
                Log.i(TAG, stus.toString());
            }
        });

Log打印

[Student{id='1'name='A', age=23},
  Student{id='2'name='B', age=33}, 
  Student{id='3'name='C', age=24}, 
  Student{id='4'name='D', age=24}, 
  Student{id='5'name='E', age=33}, 
  Student{id='6'name='F', age=23}]

示例解析

先看Log打印,可以清晰的看到打印的是一个List,而示例代码中,创建的Observable是通过 Observable.from()创建的,而且每次调用onNext发射一个Student对象。而通过toList操作符将Observable转换为Observable

toMap

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

toMap操作符将原Observable发射的所有数据项收集到到一个Map(默认是HashMap)然后发射这个Map。其变体可以提供一个用于生成Map的Key的函数,还可以提供一个函数转换数据项到Map存储的值(默认数据项本身就是值)。

toMap默认不在任何特定的调度器上执行。

API

Javadoc: toMap(Func1)
Javadoc: toMap(Func1,Func1)
Javadoc: toMap(Func1,Func1,Func0)

示例代码

Observable.from(getListOfStudent())
        .subscribeOn(Schedulers.io())
        .toMap(new Func1<Student, Integer>() {

            @Override
            public Integer call(Student student) {
                return student.getId();
            }
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<Map<Integer, Student>>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Map<Integer, Student> integerStudentMap) {
                Log.i(TAG, integerStudentMap.toString());
            }
        });

Log打印

{4=Student{id='4'name='D', age=24}, 
 1=Student{id='1'name='A', age=23}, 
 6=Student{id='6'name='F', age=23},
 5=Student{id='5'name='E', age=33}, 
 3=Student{id='3'name='C', age=24},
 2=Student{id='2'name='B', age=33}}

示例解析

示例代码中,Observable通过。toMap(Func1)将原Observable发送的数据保存到一个MAP中,并在参数函数中,设定sutdent的id属性作为key。细看Log打印正是如此。

toMultiMap

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

toMultiMap操作符类似于toMap操作符,不同的是,它生成的这个Map同时还是一个ArrayList(默认是AarryList,可通过在函数参数中修改)。

toMultiMap默认不在任何特定的调度器上执行。

API

Javadoc: toMultiMap(Func1))
Javadoc: toMultiMap(Func1,Func1))
Javadoc: toMultiMap(Func1,Func1,Func0))
Javadoc: toMultiMap(Func1,Func1,Func0,Func1))

示例代码

Observable.from(getListOfStudent())
        .subscribeOn(Schedulers.io())
        .toMultimap(new Func1<Student, Integer>() {

            @Override
            public Integer call(Student student) {
                return student.getId();
            }
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<Map<Integer, Collection<Student>>>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Map<Integer, Collection<Student>> integerCollectionMap) {
                Log.i(TAG, integerCollectionMap.toString());
            }
        });

Log打印

{4=[Student{id='4'name='D', age=24}], 
 1=[Student{id='1'name='A', age=23}], 
 6=[Student{id='6'name='F', age=23}], 
 5=[Student{id='5'name='E', age=33}], 
 3=[Student{id='3'name='C', age=24}], 
 2=[Student{id='2'name='B', age=33}]}

示例解析

示例代码中,Observable通过。toMap(Func1)将原Observable发送的数据保存到一个MAP中,并在参数函数中,设定sutdent的id属性作为key。但toMultimap操作符在将数据保存到MAP前,先将数据保存到Collection,而toMap操作符将数据直接保存到MAP中,并没有再包裹一层
Collection。

toSortedList

流程图

Image may be NSFW.
Clik here to view.
这里写图片描述

概述

toSortedList操作符类似于toList操作符,不同的是,它将对产生的列表排序,默认是自然升序,如果发射的数据项没有实现Comparable接口,会抛出一个异常。当然,若发射的数据项没有实现Comparable接口,可以使用toSortedList(Func2)变体,其传递函数参数作为用于比较两个数据项,这是toSortedList不会使用Comparable接口。

API

Javadoc: toSortedList()
Javadoc: toSortedList(Func2)

示例代码

Observable.from(getListOfStudent())
        .subscribeOn(Schedulers.io())
        .toSortedList(new Func2<Student, Student, Integer>() {
            @Override
            public Integer call(Student student, Student student2) {
                return student.getAge() - student2.getAge();
            }
        }) .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<List<Student>>() {

            @Override
            public void onStart() {
                super.onStart();
                mAdaStudent.clear();
            }

            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(List<Student> students) {
                Log.i(TAG, students.toString());
                mAdaStudent.addData(students);
            }
        });

Log打印

[Student{id='1'name='A', age=23}, 
 Student{id='6'name='F', age=23}, 
 Student{id='3'name='C', age=24},
 Student{id='4'name='D', age=24}, 
 Student{id='2'name='B', age=33}, 
 Student{id='5'name='E', age=33}]
作者:IO_Field 发表于2016/9/5 23:10:05 原文链接
阅读:51 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles