Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

RxJava之辅助操作符

$
0
0

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

delay

流程图

这里写图片描述

概述

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

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

在RxJava中,delay()操作符有很多变体,下面一一介绍其变体:
这里写图片描述
delay(long,TimeUnit)和delay(long,TimeUnit, scheduler)变体接受一个定义时长的参数(包括时长和时间单位)。每当原Observable发射一项数据,delay就启动一个定时器,当定时器过了给定的时间段时,delay创建并返回一个Observable,其与原Observable发射相同的数据项。

delay(long,TimeUnit)和delay(long,TimeUnit, scheduler)默认在computation调度器上执行,可以通过参数指定使用其它的调度器。
这里写图片描述
delay(Func1))变体不采用时间参数,而是接受一个函数参数,针对原Observable发射的数据,创建并返回一个Observable,暂且命名为_Observable,同时订阅这个_Observable。当任何一个_Observable终止时,delay()返回的_Observable就发射与其关联的那项数据。该变体默认不在任何特定的调度器上执行。
这里写图片描述
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

流程图

这里写图片描述

概述

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

在RxJava中实现了很多do操作符的变体,下面一一介绍:
这里写图片描述
doOnEach操作符可注册一个回调,它产生的Observable每发射一项数据就会调用它一次。可以以Action的形式传递参数给它,这个Action接受一个onNext的变体Notification作为它的唯一参数,也可以传递一个Observable给doOnEach,这个Observable的onNext会被调用,就好像它订阅了原Observable一样。
这里写图片描述
doOnNext操作符类似于doOnEach(Action1),但是它的Action不是接受一个Notification参数,而是接受发射的数据项。
这里写图片描述
doOnSubscribe操作符注册一个动作,当观察者订阅它生成的Observable它就会被调用。
这里写图片描述
doOnUnsubscribe操作符注册一个动作,当观察者取消订阅它生成的Observable它就会被调用。
这里写图片描述
doOnCompleted 操作符注册一个动作,当它产生的Observable正常终止调用onCompleted时会被调用。
这里写图片描述
doOnError 操作符注册一个动作,当它产生的Observable异常终止调用onError时会被调用。
这里写图片描述
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

示例解析

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

materialize

流程图

这里写图片描述

概述

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

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

API

Javadoc: materialize()

dematerialize

流程图

这里写图片描述

概述

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

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

API

Javadoc: dematerialize()

observeOn

流程图

这里写图片描述

概述

observeOn操作符指定Observable在一个特定的调度器上发送通知给观察者 (调用观察者的onNext, onCompleted, onError方法)。
这里写图片描述
当遇到一个异常时ObserveOn会立即向前传递这个onError终止通知,它不会等待Observable接受任何之前它已经收到但还没有发射的数据项。这可能意味着onError通知会跳到(并丢弃)原Observable发射的数据项前面,正如图例上展示的。

API

Javadoc: observeOn(Scheduler)

subscribeOn

流程图

这里写图片描述

概述

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

API

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

serialize

流程图

这里写图片描述

概述

一个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

流程图

这里写图片描述

概述

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

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

API

Javadoc: timeInterval()
Javadoc: timeInterval(Scheduler)

timeout

流程图

这里写图片描述

概述

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

在RxJava中有很多timeout操作符的变体,以满足各种情况下的需求。下面一一描述:
这里写图片描述
timeout(long,TimeUnit)变体接受时间参数和时间单位参数,来设定间隔时长,每当原Observable发射了一项数据,timeout就启动一个计时器,如果计时器超过了指定指定的时长而原Observable没有发射另一项数据,timeout就抛出TimeoutException,以一个错误通知终止Observable。
这里写图片描述
timeout(long,TimeUnit,Observable)和timeout(long,TimeUnit,Observable,Scheduler)变体不会发送错误通知终止,而是重新订阅备用的Observable并发射其数据项。她们默认在computation调度器上执行,而timeout(long,TimeUnit,Observable,Scheduler)变体可以通过Scheduler参数指定执行调度器。
这里写图片描述
timeout(Func1)变体在原Observable发送一个数据时,不是启动一个计时器,而是创建并返回一个_Observable,若_Observable终止时,原Observable还没有发送数据,timeout就抛出TimeoutException,以一个错误通知终止Observable。该变体默认在immediate调度器上执行。
这里写图片描述
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

流程图

这里写图片描述

概述

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

流程图

这里写图片描述

概述

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

流程图

这里写图片描述

概述

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

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

getIterator

流程图

这里写图片描述

概述

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

流程图

这里写图片描述

概述

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

流程图

这里写图片描述

概述

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

流程图

这里写图片描述

概述

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

流程图

这里写图片描述

概述

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

流程图

这里写图片描述

概述

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

流程图

这里写图片描述

概述

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



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>