rxjava3.0 -操作符

1,480 阅读31分钟

rxjava3.0学习笔记二-操作符

[TOC]

1.组合操作符 Combining Observables

本节介绍可以用于组合多个observable的操作符。

1.1 startWith

在开始从可观察对象中发出项之前,发出一个指定的项序列。

Observable.just("hello", "world")
        .startWith(Observable.just("rxjava"))
        .subscribe(System.out::println);

输出如下 rxjava hello world

1.2 mergeWith 合并

将多个observable组合成一个。任何来自源Observable的onError通知都会立即被传递给观察者,并终止合并后的Observable。

Observable.just(1,2)
 .mergeWith(Observable.error(new RuntimeException()))
        .mergeWith(Observable.just(3,4))
        .subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Throwable {
                System.out.println(integer);
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Throwable {
                System.out.println(throwable);
            }
        });
        

如果注销掉 .mergeWith(Observable.error(new RuntimeException()))

输出

1

2

3

4 ,

如果不注销,则输出

1 2 java.lang.RuntimeException

1.2 mergeDelayError 组合

将多个observable组合成一个,任何从源可观察对象传递的onError通知都将被保留,直到所有合并的可观察对象完成,并且只有到那时才会传递给观察者。

Observable<String> observable0 = Observable.just("1","2");
Observable<String> observable1 = Observable.error(new IllegalArgumentException(""));
Observable<String> observable2 = Observable.just("3","4");
Observable.mergeDelayError(observable0,observable1,observable2)
        .subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Throwable {
                System.out.println(s);
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Throwable {
                System.out.println(throwable);
            }
        });

输出

1 2 3 4 java.lang.IllegalArgumentException:

和mergeWith不同的是,Observable.error并不影响后面的 Observable.just。

1.3 zip 压缩

通过指定的函数将两个或多个observable发出的项集合组合在一起,并基于此函数的结果发出项。

Observable<String> firstNames = Observable.just("张三","李四","王五");
Observable<String> lastNames = Observable.just("大傻","二狗","三毛");
firstNames.zipWith(lastNames, new BiFunction<String, String, StringBuilder>() {
    @Override
    public StringBuilder apply(String s, String s2) throws Throwable {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(s).append("-").append(s2);
        return stringBuilder;
    }
}).subscribe(new Consumer<StringBuilder>() {
    @Override
    public void accept(StringBuilder stringBuilder) throws Throwable {
        System.out.println(stringBuilder.toString());
    }
});

输出

张三-大傻 李四-二狗 王五-三毛

1.4 combineLatest

当一个项目被两个Observable中的任何一个发出时,通过一个指定的函数将每个Observable发出的最新的项目组合起来,并基于这个函数的结果发出项目。

Observable<Long> newsRefreshes = Observable.interval(100, TimeUnit.MILLISECONDS);
Observable<Long> watherRefreshs = Observable.interval(50,TimeUnit.MILLISECONDS);
Observable.combineLatest(newsRefreshes, watherRefreshs, new BiFunction<Long, Long, String>() {
    @Override
    public String apply(Long newsRefreshesTime, Long watherRefreshsTime) throws Throwable {
        return "newsRefreshes 定时次数:"+newsRefreshesTime +"\twatherRefreshsTime定时次数:"+watherRefreshsTime;
    }
}).subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Throwable {
        System.out.println(s);
    }
});

输出如下,

newsRefreshes 定时次数:0 watherRefreshsTime定时次数:1 newsRefreshes 定时次数:0 watherRefreshsTime定时次数:2 newsRefreshes 定时次数:0 watherRefreshsTime定时次数:3 newsRefreshes 定时次数:1 watherRefreshsTime定时次数:3 newsRefreshes 定时次数:1 watherRefreshsTime定时次数:4 newsRefreshes 定时次数:1 watherRefreshsTime定时次数:5 newsRefreshes 定时次数:2 watherRefreshsTime定时次数:5 newsRefreshes 定时次数:2 watherRefreshsTime定时次数:6 newsRefreshes 定时次数:2 watherRefreshsTime定时次数:7

1.5 switchOnNext

将一个发出Observable的Observable转换为一个单独的Observable,该Observable会发出那些最近发出的Observable所发出的项。.

Observable<Observable<String>> timeIntervals
                = Observable.interval(200,TimeUnit.MILLISECONDS)
                .map(new Function<Long, Observable<String>>() {
                    @Override
                    public Observable<String> apply(Long outerTicks) throws Throwable {
                        return Observable.interval(100,TimeUnit.MILLISECONDS)
                                .map(new Function<Long, String>() {
                                    @Override
                                    public String apply(Long innerTicks) throws Throwable {
                                        return  "outerTicks: " + outerTicks + " - innerTicks: " + innerTicks;
                                    }
                                });
                    }
                });
        Observable.switchOnNext(timeIntervals).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Throwable {
                System.out.println(s);
            }
        });

输出如下。

outerTicks: 0 - innerTicks: 0 outerTicks: 1 - innerTicks: 0 outerTicks: 2 - innerTicks: 0 outerTicks: 3 - innerTicks: 0 outerTicks: 4 - innerTicks: 0 outerTicks: 5 - innerTicks: 0 outerTicks: 6 - innerTicks: 0 outerTicks: 7 - innerTicks: 0 outerTicks: 8 - innerTicks: 0 outerTicks: 8 - innerTicks: 1

1.6其他组合操作符

join( ) and groupJoin( )

and( ), then( ), and when( )

2 条件和布尔运算操作符 Conditional and Boolean Operators

本节将介绍一些操作符,你可以使用这些操作符有条件地发出或转换observable,或者对它们进行布尔运算:

2.1 条件操作符

1 amb 二Observables选 一

给定两个或多个源Observables,从第一个Observables中发射所有的item来发射一个item

单纯丢弃第二个Observables的数据?

Observable<Integer> source1 = Observable.range(1,5)
                .delay(2, TimeUnit.SECONDS)
                .doOnNext(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Throwable {
                System.out.println("source1 doOnNext:"+integer);
            }
        });
        Observable<Integer> source2 = Observable.range(6,5)
                .delay(1, TimeUnit.SECONDS)
                .doOnNext(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Throwable {
                System.out.println("source2 doOnNext:"+integer);
            }
        });

        Observable.amb(new ArrayList<>(Arrays.asList(source1,source2)))
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer next) throws Throwable {
                        System.out.println("next :"+next);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Throwable {
                        System.out.println("next :"+throwable);
                    }
                });

输出如下:

source2 doOnNext:6 next :6 source2 doOnNext:7 next :7 source2 doOnNext:8 next :8 source2 doOnNext:9 next :9 source2 doOnNext:10 next :10

2 defaultIfEmpty

从源可观察对象中发出项,或者如果源可观察对象在没有发出项之后完成,则发出一个默认项

 Observable
                .empty()
//                .just(2)
                //如果上流没有发出任何的项,则默认发出1
                .defaultIfEmpty(1)
                .blockingSubscribe( next -> {
                    System.out.println("onNext:"+next);
                },throwable -> {
                    System.out.println("onError:"+throwable);
                },()->{
                    System.out.println("onComplete");
                });

输出

onNext:1 onComplete

如果不加.defaultIfEmpty(1)

则只输出

onComplete

3 skipUntil 跳过直到

丢弃源可观察对象发出的项,直到第二个可观察对象发出一个项,然后发出源可观察对象的其余项

Observable observable1 = Observable.range(1,10).doOnNext(next->{
    System.out.println("observable1 onNext:"+next);
    Thread.sleep(1000);
});
observable1.skipUntil(Observable.timer(3,TimeUnit.SECONDS))
        .subscribe(next->{
            System.out.println("next:"+next);
        },error->{
            System.out.println("error:"+error);
        },()->{
            System.out.println("onComplete");
        });

observable1从0开始发送,但观察者直到第三秒(Observable.timer(3,TimeUnit.SECONDS)开始发出第一个项时,观察者才开始收到数据,前面的数据都丢弃。

输出结果如下

observable1 doOnNext:1 observable1 doOnNext:2 observable1 doOnNext:3 timer doOnNext:0 Consumer onNext:3 observable1 doOnNext:4 Consumer onNext:4 observable1 doOnNext:5

4 skipWhile

丢弃Observable发出的项,直到指定的条件为假,然后发出余下的items

例如skipWhile(next-> next <5),在next<5成立时,不发出items,直到next<5不成立。

Observable.range(1,10)
        .skipWhile(next-> next <5)
        .subscribe(next->{
           System.out.println("onNext:"+next);
        },error->{
            System.out.println("onError:"+error);
        },()->{
            System.out.println("onComplete");
        });

输出结果如下

onNext:5 onNext:6 onNext:7 onNext:8 onNext:9 onNext:10 onComplete

5 takeUntil

从源可观察对象中发出项,直到第二个可观察对象发出项或发出通知。

直到第一个条件成立就停止,和skipUntil相反,skipUntil是直到条件成立才开始。

Observable.range(1,10)
        .takeUntil(value -> value > 5)
        .subscribe(next->{
            System.out.println("onNext:"+next);
        },error->{
            System.out.println("onError:"+error);
        },()->{
            System.out.println("onComplete");
        });

输出

onNext:1 onNext:2 onNext:3 onNext:4 onNext:5 onNext:6 onComplete

6 takeWhile

只要指定的条件为真,就会发出Observable所发出的项,然后跳过剩下的部分

和skipWhile相反,skipWhile是条件为真就跳过,不发送items。

Observable.range(1, 10)
        .takeWhile(value -> value <= 5)
        .subscribe(next -> System.out.println("onNext:" + next),
                error -> System.out.println("onError:" + error),
                () -> System.out.println("onComplete"));

输出

onNext:1 onNext:2 onNext:3 onNext:4 onNext:5 onComplete

2.2布尔操作符 Boolean Operators

1.all 是否所有符合条件

判断Observable发出的所有项是否满足某些条件

Flowable.range(1,10)
        .doOnNext(next -> System.out.println(next))
        .all(integer -> integer<5)
        .blockingSubscribe(success->System.out.println("success:"+success));

如果.all(integer -> integer<=10) 则输出 true

如果.all(integer -> integer<10) 则输出false

2.contains 是否包含某个item

确定一个可观察对象是否包含发出一个特定的条目

Flowable.range(1,10)
        .doOnNext(next -> System.out.println(next))
        .contains(4)
        .blockingSubscribe(result -> System.out.println("result:"+result));

输出

1 2 3 4 result:true

3. isEmpty 是否是empty()

确定source Publisher 是否为空

Flowable.empty()
        .isEmpty()
        .subscribe(isEmpty -> System.out.println("isEmpty:"+isEmpty));

输出 isEmpty:true

4.sequenceEqual

测试两个observable发出的序列的相等性

Flowable<Integer> flowable1 = Flowable.range(1,3)
        .doOnNext(next ->System.out.println("flowable1 onNext:"+next));
Flowable<Integer> flowable2 = Flowable.range(1,3)
        .doOnNext(next ->System.out.println("flowable2 onNext:"+next));
Flowable.sequenceEqual(Flowable.fromPublisher(flowable1),Flowable.fromPublisher(flowable2))
        .blockingSubscribe(sequenceEqual->System.out.println("sequenceEqual:"+sequenceEqual));

flowable1 onNext:1 flowable2 onNext:1 flowable1 onNext:2 flowable2 onNext:2 flowable1 onNext:3 flowable2 onNext:3 sequenceEqual:true

3.可连接观察对象的操作符 Connectable Observable Operators

本节解释ConnectableObservable子类及其操作符

Connectable Observable类似于普通的Observable,不同之处在于它在被订阅时不会开始发出项,而只有在它的connect()方法被调用时才会发出项。通过这种方式,你可以等待所有预定的订阅器都订阅这个可观察对象,然后这个可观察对象才开始发出项。

Observable<Long> observable = Observable.interval(1,TimeUnit.SECONDS);
observable.subscribe(next->System.out.println("Consumer1 onNext:"+next));

Thread.sleep(2000);

observable.subscribe(next2->System.out.println("------Consumer2 onNext:"+next2));

输出如下,两个Consumer在某一个时间并不是一样的数据。

Consumer1 onNext:0 Consumer1 onNext:1 Consumer1 onNext:2 ------Consumer2 onNext:0 Consumer1 onNext:3 ------Consumer2 onNext:1 Consumer1 onNext:4 ------Consumer2 onNext:2 ------Consumer2 onNext:3 Consumer1 onNext:5 ------Consumer2 onNext:4 Consumer1 onNext:6

ConnectableObservable<Long> connectableObservable
        = Observable.interval(1,TimeUnit.SECONDS)
        .publish();
connectableObservable.subscribe(next->System.out.println("Consumer1 onNext:"+next));
Thread.sleep(2000);
connectableObservable.subscribe(next->System.out.println("---Consumer2 onNext:"+next));
connectableObservable.connect();

输出如下,两个Consumer输出是一样的。

Consumer1 onNext:0 ---Consumer2 onNext:0 Consumer1 onNext:1 ---Consumer2 onNext:1 Consumer1 onNext:2 ---Consumer2 onNext:2 Consumer1 onNext:3 ---Consumer2 onNext:3

3.1 ConnectableObservable.connect( )

指示一个可连接的Observable开始发射项目,只有connect之后才发送items,而不是订阅后就发送items

Disposable disposable;

ConnectableObservable<Integer> connectableObservable = Observable.just(1).publish();
connectableObservable.subscribe(next -> System.out.println("onNext:"+next));
//Disposable disposable = connectableObservable.connect();
Disposable disposable;
connectableObservable.connect(new Consumer<Disposable>() {
    @Override
    public void accept(Disposable disposable) throws Throwable {
        disposable = disposable;
        System.out.println("connect accept disposable:"+disposable);
    }
});

输出

connect accept disposable:[Lio.reactivex.rxjava3.internal.operators.observable.ObservablePublish$InnerDisposable;@6d86b085 onNext:1

3.2 Observable.publish( )

表示一个可观察对象为一个可连接的可观察对象

同上

3.3 Observable.replay( )

确保所有订阅器都能看到发出的项的相同序列,即使它们是在Observable开始发出项之后订阅

ConnectableObservable<Long> connectableObservable = Observable.interval(1, TimeUnit.SECONDS)
                .replay();
        connectableObservable.subscribe(next->System.out.println("onNext1:"+next));
        connectableObservable.connect();
        Thread.sleep(2000);
        System.out.println("Thread.sleep(2000)");
        connectableObservable.subscribe(next->System.out.println("-----onNext2:"+next));

输出

onNext1:0 Thread.sleep(2000) onNext1:1 -----onNext2:0 -----onNext2:1 onNext1:2 -----onNext2:2 onNext1:3 -----onNext2:3 onNext1:4 -----onNext2:4 onNext1:5 -----onNext2:5 onNext1:6 -----onNext2:6

3.4 ConnectableObservable.refCount( )

使一个可连接的可观察对象的行为像一个普通的可观察对象

以普通的为例 Observable.interval为例

 Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS);
        observable.subscribe(next2 -> System.out.println("Consumer1 onNext:" + next2),
                error -> System.out.println("Consumer1 onError:" + error),
                () -> System.out.println("Consumer1 onComplete"));

Thread.sleep(2000);

observable.subscribe(next2 -> System.out.println("--Consumer2 onNext:" + next2),
                error -> System.out.println("--Consumer2 onError:" + error),
                () -> System.out.println("--Consumer2 onComplete"));

Consumer1 onNext:0 Consumer1 onNext:1 Consumer1 onNext:2 --Consumer2 onNext:0 Consumer1 onNext:3 --Consumer2 onNext:1 Consumer1 onNext:4 --Consumer2 onNext:2 --Consumer2 onNext:3 Consumer1 onNext:5 Consumer1 onNext:6 --Consumer2 onNext:4

ConnectableObservable两个Consumer时,输出如下

ConnectableObservable<Long> connectableObservable = Observable.interval(1, TimeUnit.SECONDS)
        .publish();
connectableObservable.subscribe(next -> System.out.println("Consumer1 onNext:" + next),
        error -> System.out.println("Consumer1 onError:" + error),
        () -> System.out.println("Consumer1 onComplete"));

Thread.sleep(2000);
connectableObservable.subscribe(next -> System.out.println("---Consumer2 onNext:" + next),
        error -> System.out.println("---Consumer2 onError:" + error),
        () -> System.out.println("---Consumer2 onComplete"));
connectableObservable.connect();

Consumer1 onNext:0 ---Consumer2 onNext:0 Consumer1 onNext:1 ---Consumer2 onNext:1 Consumer1 onNext:2 ---Consumer2 onNext:2 Consumer1 onNext:3 ---Consumer2 onNext:3 Consumer1 onNext:4 ---Consumer2 onNext:4

refCount把ConnectableObservable转换成了普通的Observable,不需要connect()才发送数据,行为也和普通的Observable一样。

Observable<Long> connectableObservable = Observable.interval(1, TimeUnit.SECONDS)
        .publish().refCount();
connectableObservable.subscribe(next -> System.out.println("Consumer1 onNext:" + next),
        error -> System.out.println("Consumer1 onError:" + error),
        () -> System.out.println("Consumer1 onComplete"));

Thread.sleep(2000);
connectableObservable.subscribe(next -> System.out.println("---Consumer2 onNext:" + next),
        error -> System.out.println("---Consumer2 onError:" + error),
        () -> System.out.println("---Consumer2 onComplete"));

4.创建类操作符 Creating Observables

1. create 创建

构造一个安全的响应式类型实例,由使用者订阅该实例。运行用户提供的函数,并为该函数提供特定类型的Emitter,以生成指定业务逻辑所需的信号。

这个方法允许将非响应式(通常是侦听器/回调式)世界与响应式世界连接起来。

ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
ObservableOnSubscribe<String> handler = new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
        ScheduledFuture<Object> future = executorService.schedule(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                emitter.onNext("Hello");
                emitter.onNext("World");
                emitter.onComplete();
                return null;
            }
        },1,TimeUnit.SECONDS);
        emitter.setCancellable(()->future.cancel(false));
    }
};

Observable<String> observable = Observable.create(handler);
observable.subscribe(next->System.out.println("onNext:"+next)
        ,error->System.out.println("onError:"+error),
        ()->System.out.println("onComplete"));

输出

onNext:Hello onNext:World onComplete

2.defer 延时处理

当使用者订阅了响应式类型时,调用用户提供的java.util.concurrent.Callable,以便Callable能够生成实际的响应式实例来将信号传递给使用者。

defer允许:

1.将每个消费者的状态与生成的响应性实例相关联,

2.允许在实际/生成的响应实例被订阅之前执行副作用,

3.将热源(Subjects and Processors))转换为冷源,基本上是让这些热源在用户订阅之前不存在。

defer和just的区别

  private static String createData() {
        System.out.println("hello world");
        return String.valueOf(System.currentTimeMillis());
    }

Observable<String> observable = Observable.just(createData())
        .doOnSubscribe(disposable -> System.out.println("doOnSubscribe"));

即使不订阅,Observable.just在装配阶段就已经调用了createData(),

Observable.defer如果不订阅,是不会产生调用createData()方法,Observable.create和Observable.defer类似,也是不订阅不产生数据。

Observable<String> observable = Observable.defer(() -> {
    return Observable.just(createData());
}).doOnSubscribe(disposable->System.out.println("doOnSubscribe"));

3.range

为每个消费者生成一个值序列。range()方法生成Integer整数,rangeLong()生成long。

String greeting = "Hello World";
Observable<Integer> indexes = Observable.range(0,greeting.length());
Observable<Character> characterObservable = indexes.map(index->greeting.charAt(index));
characterObservable.subscribe(character->System.out.println(character),
        error-> error.printStackTrace(),
        ()->System.out.println("onComplete"));

输出结果

H e l l o

W o r l d onComplete

4.interval 间隔

周期性地生成一个无限的、不断增加的数字(Long类型)。变量intervalRange会生成数量有限的这样的数字。

//Observable<Long> clock = Observable.interval(1,TimeUnit.SECONDS);
Observable<Long> clock = Observable.intervalRange(0,10,0,1,TimeUnit.SECONDS);
clock.subscribe(time->{
    if(time %2 == 0) {
        System.out.println("tick");
    } else {
        System.out.println("tock");
    }
});

定时调用

5.timer

在指定的时间之后,这个反应式源发出一个0L信号(然后完成Flowable和Observable)

Observable<Long> eggTimer = Observable.timer(5,TimeUnit.SECONDS);
eggTimer.blockingSubscribe(value ->System.out.println("egg is ready!:"+value));

输出

egg is ready!:0

6.empty

这种类型的信号源在订阅后立即完成。

Observable<String> empty = Observable.empty();
empty.subscribe(next->System.out.println("This should never be printed!"),
        error->System.out.println("Or this!"),
        ()->System.out.println("Done will be printed."));

输出

Done will be printed.

7.never

这种类型的源不会发出任何onNext、onSuccess、onError或onComplete信号。这种类型的反应式源在组合运算符中测试或“禁用”某些源是有用的。

Observable<String> never = Observable.never();

never.subscribe(
        v -> System.out.println("This should never be printed!"),
        error -> System.out.println("Or this!"),
        () -> System.out.println("This neither!"));

什么都没有输出

8.error

提示一个错误,可以是预先存在的,也可以是通过java.util.concurrent.Callable生成的。对消费者来说是可调用的。

Observable<String> error = Observable.error(new IOException());
error.subscribe(v->System.out.println("This should never be printed!"),
        e-> e.printStackTrace(),
        ()->System.out.println("This neither!"));

e.printStackTrace()会向控制台打印错误

一个典型的用例是利用onErrorResumeNext有条件地映射或抑制链中的异常:

Observable<String> observable = Observable.fromCallable(() -> {
    if (Math.random() < 0.5) {
        throw new IOException();
    }
    throw new IllegalArgumentException();
});

Observable<String> result = observable.onErrorResumeNext(error -> {
    if (error instanceof IllegalArgumentException) {
        return Observable.empty();
    }
    return Observable.error(error);
});

for (int i = 0; i < 10; i++) {
    result.subscribe(
        v -> System.out.println("This should never be printed!"), 
        error -> error.printStackTrace(),
        () -> System.out.println("Done"));
}

5.错误处理操作符 Error Handling Operators

1.doOnError

指示响应类型在遇到错误时调用给定的io.reactivex.functions.Consumer。

Observable.error(new IOException("Something went wrong"))
        .doOnError(error->System.out.println("The error message is:"+error.getMessage()))
        .subscribe(next->System.out.println("onNext should never be printed!"),
                error->error.printStackTrace(),
                ()->System.out.println("onCompleta should never be printed!")) ;

输出

The error message is:Something went wrong

并输出错误堆栈。

2.onErrorComplete

指示响应式类型接收错误事件并将其替换为完成事件。

可选地,可以指定io.reactivex.functions.Predicate,以便对何时应该用完成事件替换错误事件和何时不应该替换错误事件提供更多的控制。

Completable.fromAction(() -> {
    throw new IOException();
}).onErrorComplete(error -> {
    //当返回true时,调用onComplete而不是onError
    return error instanceof IOException;
}).subscribe(() -> System.out.println("onComplete"),
        error -> error.printStackTrace());

输出

onComplete

3.onErrorResumeNext

指示反应式类型在遇到错误时发出一系列项。

Observable<Integer> numbers = Observable.generate(()->1,(state,emitter)->{
    emitter.onNext(state);
    return state + 1;
});
numbers.scan(Math::multiplyExact)
        .onErrorResumeNext(error-> Observable.empty())
        .subscribe(System.out::println,
                error->System.out.println("onError should not be printed!"));

正常 Math::multiplyExact会抛出异常

但onErrorResumeNext(error-> Observable.empty())使异常不会调用到onError,而是调用到了onComplete

可以通过判断 error是Exception还是Error来更细化的处理错误。

输出结果为

1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600

4.onErrorReturn

指示反应类型在遇到错误时发出由指定的io.reactivex.functions.Function返回的项。

Single.just("2A")
        .map(v -> Integer.parseInt(v, 10))
        .onErrorReturn(error -> {
            if (error instanceof NumberFormatException) return 0;
            else throw new IllegalArgumentException();
        })
        .subscribe(
                System.out::println,
                error -> System.err.println("onError should not be printed!"));

输出

0

5.onErrorReturnItem

指示响应类型在遇到错误时发出特定项。

Single.just("2A")
    .map(v -> Integer.parseInt(v, 10))
    .onErrorReturnItem(0)
    .subscribe(
        System.out::println,
        error -> System.err.println("onError should not be printed!"));

输出

0

6.onExceptionResumeNext

指示响应类型在遇到java.lang.Exception后继续发出项。不像onErrorResumeNext,这个允许其他类型的Throwable继续通过。

好像rxjava3没有了这一个操作符。通过判断error的值是Exception还是Error来决定是否继

  Observable exception = Observable.error(new IOException())
                .onErrorResumeNext(error -> {
                    if (error instanceof Exception) {
                        return Observable.just("This value will be used to recover from the IOException");
                    } else {
                        return Observable.error(error);
                    }
                });

        Observable error = Observable.error(new Error())
                .onErrorResumeNext(errorValue -> {
                    if (errorValue instanceof Error) {
                        return Observable.error(errorValue);
                    } else {
                        return Observable.just(("This value will not be used"));
                    }
                });
        Observable.concat(exception, error)
                .subscribe(message -> System.out.println("onNext:" + message),
                        error1 -> System.out.println("onError:" + error1));

输出

onNext:This value will be used to recover from the IOException onError:java.lang.Error

7.retry

指示响应式类型在遇到错误时重新订阅源响应式类型,希望它能顺利完成。

输出如下

System.out.println("retry start:"+System.currentTimeMillis());
Observable<Long> source = Observable.interval(1, 1, TimeUnit.SECONDS)
        .flatMap(x -> {
            if (x > 2) return Observable.error(new IOException("Something went wrong!"));
            else return Observable.just(x);
        });

source.retry((retryCount, error) -> retryCount < 3)
        .blockingSubscribe(x -> System.out.println("onNext:" + x+"\t"+System.currentTimeMillis()),
                error -> System.out.println("onError:" + error.getMessage()));

retry start:1631669961037 onNext:0 1631669962282 onNext:1 1631669963277 onNext:2 1631669964290 onNext:0 1631669966305 onNext:1 1631669967299 onNext:2 1631669968299 onNext:0 1631669970320 onNext:1 1631669971316 onNext:2 1631669972309 onError:Something went wrong!

8.retryUntil

如果遇到错误,指示响应类型重新订阅源响应类型,直到给定的io.reactivex.functions. boolean返回true。

LongAdder errorCounter = new LongAdder();
Observable<Long> source = Observable.interval(1, 1, TimeUnit.SECONDS)
        .flatMap(x -> {
            if (x > 2) return Observable.error(new IOException("Something went wrong!"));
            else return Observable.just(x);
        }).doOnError(error -> errorCounter.increment());
source.retryUntil(() -> errorCounter.intValue() >= 3)
        .blockingSubscribe(x -> System.out.println("onNext:" + x),
                error -> System.out.println("onError:" + error.getMessage()));

onNext:0 onNext:1 onNext:2 onNext:0 onNext:1 onNext:2 onNext:0 onNext:1 onNext:2 onError:Something went wrong!

9.retryWhen

指示响应类型将任何错误传递给另一个Observable或Flowable,以决定是否重新订阅源。

Observable<Long> source = Observable.interval(1,1,TimeUnit.SECONDS)
        .flatMap(x->{
            if(x >=2) return Observable.error(new IOException("Something went wrong!"));
            else return Observable.just(x);
        });
source.retryWhen(errors -> {
    return errors.map(error->1)
            .scan(Math::addExact)
            .doOnNext(errorCount->System.out.println("No. of errors:"+errorCount))
            .takeWhile(errorCount->errorCount<3)
            .flatMapSingle(errorCount ->Single.timer(errorCount,TimeUnit.SECONDS));
}).blockingSubscribe(x->System.out.println("onNext:"+x),
        Throwable::printStackTrace,
        ()->System.out.println("onComplete"));

errors:io.reactivex.rxjava3.subjects.SerializedSubject@b97c004 flatMap x:0 onNext:0 flatMap x:1 onNext:1 flatMap x:2 error:java.io.IOException: Something went wrong! No. of errors:1 flatMap x:0 onNext:0 flatMap x:1 onNext:1 flatMap x:2 error:java.io.IOException: Something went wrong! No. of errors:2 flatMap x:0 onNext:0 flatMap x:1 onNext:1 flatMap x:2 error:java.io.IOException: Something went wrong! No. of errors:3 onComplete

6.过滤操作符 Observables

1 debounce 防抖动

在给定的超时值过期之前,删除由反应式源发出的项,这些项后面跟着较新的项。每次发射都会重置计时器。

该操作符跟踪最近发出的项,只有当足够长的时间过去而源没有发出任何其他项时,才发出此项。

Observable<String> source = Observable.create(emitter -> {
    emitter.onNext("A");

    Thread.sleep(1_500);
    emitter.onNext("B");

    Thread.sleep(500);
    emitter.onNext("C");

    Thread.sleep(250);
    emitter.onNext("D");

    Thread.sleep(2_000);
    emitter.onNext("E");
    emitter.onComplete();
});

source.subscribeOn(Schedulers.io())
        .debounce(1, TimeUnit.SECONDS)
        .blockingSubscribe(
                item -> System.out.println("onNext: " + item),
                Throwable::printStackTrace,
                () -> System.out.println("onComplete"));

2.distinct 去重

通过只发射与前一项比较不同的项来过滤反应式源

可以指定io.reactivex.functions.Function,将源发出的每个项投影到一个新值中,该新值将用于与以前的投影值进行比较。

Observable.just(3,4,4,4,4,5,6)
                .distinct()
                .subscribe(System.out::println);

输出

3 4 5 6

3.distinctUntilChanged 去连续的重

通过只发射与它们的直接前辈相比不同的项目来过滤反应式源。可以指定io.reactivex.functions.Function,将源发出的每个项投影到一个新值中,该新值将用于与以前的投影值进行比较。或者,可以指定io.reactivex.functions.BiPredicate,作为比较器函数来相互比较直接的前任。

Observable.just(1,1,2,1,2,3,3,4)
        .distinctUntilChanged()
        .subscribe(System.out::println);

输出

1 2 1 2 3 4

4.elementAt 根据下标取值

按照反应式源的排放序列,在指定的零索引处排放单个项目。如果指定的索引不在序列中,则可以指定一个默认项。

Observable source = Observable.just(1,2,3,4,5,6,7,8,9);
Maybe<Integer> element = source.elementAt(5);
element.subscribe(System.out::println);

输出

5

5.elementAtOrError

按照 reactive source的排放序列,在指定的零索引处排放单个项目,如果指定的索引不在序列中,则发出java.util.NoSuchElementException信号。

 Observable<String> source = Observable.just("Kirk", "Spock", "Chekov", "Sulu");
        Single<String> element = source.elementAtOrError(4);
        element.subscribe(
                name->System.out.println("onSuccess will not be printed!"),
                error->System.out.println("onError:"+error)
        );	

输出

onError:java.util.NoSuchElementException

6.filter 过滤

通过只发出满足指定谓词的项来筛选由 reactive source发出的项。

Observable.just(1, 2, 3, 4, 5, 6)
        .filter(x -> x % 2 == 0)
        .subscribe(System.out::println);

2 4 6

7.first 取第一个值。

只发出由 reactive source发出的第一个项,或者如果源完成时没有发出项,则发出给定的默认项。这与firstElement的不同之处在于,该操作符返回一个Single,而firstElement返回一个Maybe。

Observable<String> source = Observable.just("A", "B", "C");
Single<String> firstOrDefault = source.first("D");

firstOrDefault.subscribe(System.out::println);

输出

A

8.firstElement

只发出由 reactive source发出的第一个项,或者在源完成而没有发出项时才完成。这与first的不同之处在于,该操作符返回一个Maybe,而first返回一个Single。

Observable<String> source = Observable.just("A", "B", "C");
Maybe<String> first = source.firstElement();

first.subscribe(System.out::println);

输出

A

9.firstOrError

只发出由响应源发出的第一个项,或者如果源完成而没有发出项,则发出java.util.NoSuchElementException信号。

Observable<String> emptySource = Observable.empty();
Single<String> firstOrError = emptySource.firstOrError();

firstOrError.subscribe(
        element -> System.out.println("onSuccess will not be printed!"),
        error -> System.out.println("onError: " + error));

输出

onError: java.util.NoSuchElementException

10.ignoreElement

忽略由single或Maybe源发出的单个项,并返回一个Completable,该Completable仅从源发出错误或完成事件的信号。

Single<Long> source = Single.timer(1, TimeUnit.SECONDS);
Completable completable = source.ignoreElement();

completable.doOnComplete(() -> System.out.println("Done!"))
        .blockingAwait();

一秒后输出

Done!

11.ignoreElements 忽略所有项

忽略Observable或Flowable源中的所有项,并返回一个Completable,该Completable只从源中发出错误或完成事件的信号。

Observable<Long> source = Observable.intervalRange(1, 5, 1, 1, TimeUnit.SECONDS);
Completable completable = source.ignoreElements();

completable.doOnComplete(() -> System.out.println("Done!"))
        .blockingAwait();

5秒后输出

Done!

12.last 发出最后一项或默认值

只发出由 reactive source发出的最后一个项,或者在源完成而没有发出项时发出给定的默认项。

Observable<String> source = Observable.just("A", "B", "C");
Single<String> lastOrDefault = source.last("D");

lastOrDefault.subscribe(System.out::println);

输出

C

13.lastElement

只发出由 reactive source发出的最后一个项,或者在源完成而没有发出项时才完成。与last不同的是,该操作符返回Maybe,而last返回Single。

Observable<String> source = Observable.just("A", "B", "C");
Maybe<String> last = source.lastElement();

last.subscribe(System.out::println);

输出

C

14.lastOrError

只发出由响应源发出的最后一个项,或者如果源完成而没有发出项,则发出java.util.NoSuchElementException信号。

Observable<String> emptySource = Observable.empty();
Single<String> lastOrError = emptySource.lastOrError();

lastOrError.subscribe(
        element -> System.out.println("onSuccess will not be printed!"),
        error -> System.out.println("onError: " + error));

输出

onError: java.util.NoSuchElementException

15.ofType 根据类型过滤

通过只发出指定类型的项来筛选由 reactive source发出的项。

Observable<Number> numbers = Observable.just(1, 4.0, 3, 2.71, 2f, 7);
Observable<Integer> integers = numbers.ofType(Integer.class);

integers.subscribe((Integer x) -> System.out.println(x));

输出

1 3 7

16.sample 采样

通过在一定的时间间隔内仅发出最近发出的项目来筛选 reactive source发出的项目。

// Diagram:
// -A----B-C-------D-----E-|-->
// -0s-----c--1s---d----2s-|-->
// -----------C---------D--|-->

Observable<String> source = Observable.create(emitter -> {
    emitter.onNext("A");

    Thread.sleep(500);
    emitter.onNext("B");

    Thread.sleep(200);
    emitter.onNext("C");

    Thread.sleep(800);
    emitter.onNext("D");

    Thread.sleep(600);
    emitter.onNext("E");
    emitter.onComplete();
});

source.subscribeOn(Schedulers.io())
        .sample(1, TimeUnit.SECONDS)
        .blockingSubscribe(
                item -> System.out.println("onNext: " + item),
                Throwable::printStackTrace,
                () -> System.out.println("onComplete"));

// prints:
// onNext: C
// onNext: D
// onComplete

17.skip 跳过前n项

丢弃由 reactive source发出的前n项,并发出其余项。

Observable<Integer> source = Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

source.skip(4)
    .subscribe(System.out::println);

输出

5 6 7 8 9 10

18.skipLast 跳转最后n项

丢弃由 reactive source发出的最后n项,并发出其余项。

Observable<Integer> source = Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

source.skipLast(4)
        .subscribe(System.out::println);

输出

1 2 3 4 5 6

19.take 只取前n项

只发出由 reactive source发出的前n项。

Observable<Integer> source = Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
source.take(4)
        .subscribe(System.out::println);

1 2 3 4

20.takeLast 只取后n项

只发出由 reactive source发出的最后n项。

Observable<Integer> source = Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

source.takeLast(4)
    .subscribe(System.out::println);

7 8 9 10

21.throttleFirst 节流

在指定持续时间的连续时间窗口内仅发出由 reactive source发出的第一项。

// Diagram:
// -A----B-C-------D-----E-|-->
//  a---------1s
//                 d-------|-->
// -A--------------D-------|-->
Observable<String> source = Observable.create(emitter -> {
    emitter.onNext("A");

    Thread.sleep(500);
    emitter.onNext("B");

    Thread.sleep(200);
    emitter.onNext("C");

    Thread.sleep(800);
    emitter.onNext("D");

    Thread.sleep(600);
    emitter.onNext("E");
    emitter.onComplete();
});

source.subscribeOn(Schedulers.io())
        .throttleFirst(1, TimeUnit.SECONDS)
        .blockingSubscribe(
                item -> System.out.println("onNext: " + item),
                Throwable::printStackTrace,
                () -> System.out.println("onComplete"));

输出

onNext: A onNext: D onComplete

22.throttleLast 节流

// Diagram:
// -A----B-C-------D-----E-|-->
// -0s-----c--1s---d----2s-|-->
// -----------C---------D--|-->
Observable<String> source = Observable.create(emitter -> {
    emitter.onNext("A");

    Thread.sleep(500);
    emitter.onNext("B");

    Thread.sleep(200);
    emitter.onNext("C");

    Thread.sleep(800);
    emitter.onNext("D");

    Thread.sleep(600);
    emitter.onNext("E");
    emitter.onComplete();
});

source.subscribeOn(Schedulers.io())
        .throttleLatest(1, TimeUnit.SECONDS)
        .blockingSubscribe(
                item -> System.out.println("onNext: " + item),
                Throwable::printStackTrace,
                () -> System.out.println("onComplete"));

输出

onNext: A onNext: C onNext: D onComplete

23.throttleLatest 节流

发出由 reactive source发出的下一个项,然后在它们之间指定的超时时间过去时周期性地发出最新项(如果有的话)。

// Diagram:
// -A----B-C-------D-----E-|-->
// -a------c--1s
//            -----d----1s
//                      -e-|-->
// -A---------C---------D--|-->

Observable<String> source = Observable.create(emitter -> {
            emitter.onNext("A");

            Thread.sleep(500);
            emitter.onNext("B");

            Thread.sleep(200);
            emitter.onNext("C");

            Thread.sleep(800);
            emitter.onNext("D");

            Thread.sleep(600);
            emitter.onNext("E");
            emitter.onComplete();
        });

        source.subscribeOn(Schedulers.io())
                .throttleLatest(1, TimeUnit.SECONDS)
                .blockingSubscribe(
                        item -> System.out.println("onNext: " + item),
                        Throwable::printStackTrace,
                        () -> System.out.println("onComplete"));

输出

onNext: A onNext: C onNext: D onComplete

24.throttleWithTimeout 节流

在给定的超时值过期之前,删除由反应式源发出的项,这些项后面跟着较新的项。每次发射都会重置计时器。

// Diagram:
// -A--------------B----C-D-------------------E-|---->
//  a---------1s
//                 b---------1s
//                      c---------1s
//                        d---------1s
//                                            e-|---->
// -----------A---------------------D-----------E-|-->

Observable<String> source = Observable.create(emitter -> {
    emitter.onNext("A");

    Thread.sleep(1_500);
    emitter.onNext("B");

    Thread.sleep(500);
    emitter.onNext("C");

    Thread.sleep(250);
    emitter.onNext("D");

    Thread.sleep(2_000);
    emitter.onNext("E");
    emitter.onComplete();
});

source.subscribeOn(Schedulers.io())
        .throttleWithTimeout(1, TimeUnit.SECONDS)
        .blockingSubscribe(
                item -> System.out.println("onNext: " + item),
                Throwable::printStackTrace,
                () -> System.out.println("onComplete"));

onNext: A onNext: D onNext: E onComplete

25.timeout 超时

*:*触发Observable或Flowable源中的项,但如果下一项没有在从上一项开始的指定超时时间内触发,则以java.util.concurrent.TimeoutException终止。对于Maybe、Single和Completable,指定的超时时间指定等待成功或完成事件到达的最大时间。如果Maybe、Single或Completable没有在给定的时间内完成,就会触发java.util.concurrent.TimeoutException。

// Diagram:
// -A-------B---C-----------D-|-->
//  a---------1s
//          b---------1s
//              c---------1s
// -A-------B---C---------X------>

Observable<String> source = Observable.create(emitter -> {
    emitter.onNext("A");

    Thread.sleep(800);
    emitter.onNext("B");

    Thread.sleep(400);
    emitter.onNext("C");

    Thread.sleep(1200);
    emitter.onNext("D");
    emitter.onComplete();
});

source.timeout(1, TimeUnit.SECONDS)
        .subscribe(
                item -> System.out.println("onNext: " + item),
                error -> System.out.println("onError: " + error),
                () -> System.out.println("onComplete will not be printed!"));

输出

onNext: A onNext: B onNext: C onError: java.util.concurrent.TimeoutException: The source did not signal an event for 1 seconds and has been terminated.

7.数学计算和集合操作符 Mathematical and Aggregate Operators

使用以下操作符,需要引入相关依赖

implementation "com.github.akarnokd:rxjava3-extensions:3.1.1"

数学运算符 Mathematical Operators

averageDouble 平均数

计算由可观察对象发出的Numbers的平均值,并将此平均值作为Double发出。

Observable<Integer> numbers = Observable.just(1, 2, 3);
MathObservable.averageDouble(numbers).subscribe((Double avg) -> System.out.println(avg));

输出

2.0

averageFloat 平均数

计算一个可观察对象发出的Numbers的平均值,并将这个平均值作为一个浮点数发出。

Observable<Integer> numbers = Observable.just(1, 2, 3);
MathObservable.averageFloat(numbers).subscribe((Float avg) -> System.out.println(avg));

输出 2.0

max 最大值

发出由源Observable发出的最大值。可以指定一个Comparator,用来比较Observable发出的元素。

Observable<Integer> numbers = Observable.just(4, 9, 5);
MathObservable.max(numbers).subscribe(System.out::println);

输出 9

下面的例子指定了一个比较器来查找源Observable中最长的字符串:

final Observable<String> names = Observable.just("Kirk", "Spock", "Chekov", "Sulu");
MathObservable.max(names, Comparator.comparingInt(String::length))
        .subscribe(System.out::println);

输出 Chekov

min 最小值

发出由源Observable发出的最小值。可以指定一个Comparator,用来比较Observable发出的元素。

Observable<Integer> numbers = Observable.just(4, 9, 5);
MathObservable.min(numbers).subscribe(System.out::println);

输出4

sumDouble 总数

添加由Observable发出的double并发出这个和。

Observable<Double> numbers = Observable.just(1.0, 2.0, 3.0);
MathObservable.sumDouble(numbers).subscribe((Double sum) -> System.out.println(sum));

输出6.0

sumFloat 总数

Observable<Float> numbers = Observable.just(1.0F, 2.0F, 3.0F);
MathObservable.sumFloat(numbers).subscribe((Float sum) -> System.out.println(sum));

输出 6.0

sumInt 总数

添加由可观察对象发出的整数并发出这个和。

Observable<Integer> numbers = Observable.range(1, 100);
MathObservable.sumInt(numbers).subscribe((Integer sum) -> System.out.println(sum));

输出5050

sumLong 总数

添加由可观察对象发出的long并发出这个和。

Observable<Long> numbers = Observable.rangeLong(1L, 100L);
MathObservable.sumLong(numbers).subscribe((Long sum) -> System.out.println(sum));

输出 5050

标准集合操作符 Standard Aggregate Operators

注意,这些标准集合操作符返回一个Single或Maybe,因为输出项的数量总是最多为1。

count 数量

计算由Observable发出的项的数量,并将此计数作为Long发出。

Observable.just(1, 2, 3).count().subscribe(System.out::println);

输出3

reduce “聚合”或“压缩”

对每个发出的项应用函数,然后只发出最终的累积值。

servable.range(1, 5)
    .reduce((product, x) -> product * x)
    .subscribe(System.out::println);

1x2x3x4x5 = 120

输出120

reduceWith

对每个发出的项应用函数,然后只发出最终的累积值。

 Observable.just(1, 2, 2, 3, 4, 4, 4, 5).reduceWith(new Supplier<TreeSet<Integer>>() {
            @Override
            public TreeSet<Integer> get() throws Throwable {
                System.out.println("TreeSet<Integer> get()");
                return new TreeSet<Integer>();
            }
        }, new BiFunction<TreeSet<Integer>, Integer, TreeSet<Integer>>() {
            @Override
            public TreeSet<Integer> apply(TreeSet<Integer> integers, Integer integer) throws Throwable {
                integers.add(integer);
                return integers;
            }
        }).subscribe(System.out::println);

输出 [1, 2, 3, 4, 5]

collect 收集

将源Observable发出的项收集到一个单一的可变数据结构中,并返回一个发出该结构的Observable。

    Observable.just("Kirk", "Spock", "Chekov", "Sulu")
                .collect(() -> new StringJoiner("-"), StringJoiner::add)
                .map(StringJoiner::toString)
                .subscribe(System.out::println);

输出 Kirk-Spock-Chekov-Sulu

collectInto 收集

将源Observable发出的项收集到一个单一的可变数据结构中,并返回一个发出该结构的Observable。

Observable.just('R', 'x', 'J', 'a', 'v', 'a')
        .collectInto(new StringBuilder(), StringBuilder::append)
        .map(StringBuilder::toString)
        .subscribe(System.out::println);

toList 转换成数组

从一个可观察对象中收集所有的项目,并将它们作为单个List发出。

Observable.just(2, 1, 3)
        .toList()
        .subscribe(System.out::println);

输出 [2, 1, 3]

toSortedList 转换成排序好的数组

从一个可观察对象中收集所有项,并将它们作为一个单独的、有序的列表发出。

Observable.just(2, 1, 3)
        .toSortedList(Comparator.reverseOrder())
        .subscribe(System.out::println);

输出 [3, 2, 1]

toMap 转换成Map键值对

将Observable发出的项目序列转换为Map,由指定的key函数指定键值。

Observable.just(1, 2, 3, 4)
        .toMap((x) -> {
            // defines the key in the Map
            return x;
        }, (x) -> {
            // defines the value that is mapped to the key
            return (x % 2 == 0) ? "even" : "odd";
        })
        .subscribe(System.out::println);

输出

{1=odd, 2=even, 3=odd, 4=even}

toMultimap

将Observable发出的项序列转换为Collection, Collection也是一个Map,由指定的key函数指定键值。

Observable.just(1, 2, 3, 4)
        .toMultimap((x) -> {
            // defines the key in the Map
            return (x % 2 == 0) ? "even" : "odd";
        }, (x) -> {
            // defines the value that is mapped to the key
            return x;
        })
        .subscribe(System.out::println);

输出 {even=[2, 4], odd=[1, 3]}

8.Parallel flows 并发

版本2.0.5引入了ParallelFlowable API,允许并行执行一些选择操作符,如map、filter、concatMap、flatMap、collect、reduce等。注意,这是Flowable(一种特定于子域的语言)的并行模式,而不是新的响应式基类型。

因此,一些典型的操作,如take, skip和许多其他的不可用,也没有ParallelObservable,因为反压是必要的,不能像预期的那样淹没并行操作符的内部队列,我们希望并行,因为在一个线程上处理数据很慢。

进入平行世界最简单的方法是使用Flowable.parallel:

ParallelFlowable<Integer> source = Flowable.range(1, 1000).parallel();

默认情况下,并行级别被设置为可用cpu的数量(Runtime.getRuntime().availableProcessors()),从顺序源的预取量设置为**Flowable.bufferSize() (**128)。

两者都可以通过parallel()的重载来指定。

ParallelFlowable遵循与Flowable相同的参数异步原则,因此,parallel()本身并不引入顺序源的异步使用,而只是准备并行流;异步是通过**runOn(Scheduler)**操作符定义的。

ParallelFlowable<Integer> psource = source.runOn(Schedulers.io());

并行度级别(ParallelFlowable.parallelism())不必与调度程序的并行度级别匹配。runOn操作符将使用同样多的Scheduler.Worker 由并行化源定义的实例。这允许ParallelFlowable通过Schedulers.computation()为CPU密集型任务工作,通过Schedulers.io()处理阻塞/IO绑定的任务,以及通过TestScheduler进行单元测试。您也可以在runOn上指定预取数量。

一旦应用了必要的并行操作,就可以通过ParallelFlowable.sequential()操作符返回到顺序的Flowable。

Flowable<Integer> result = psource.filter(v -> v % 3 == 0).map(v -> v * v).sequential();

注意,sequential不能保证流经并行运算符的值之间有任何顺序。

9.Transforming Observables 转换

您可以使用这些操作符转换由响应源(如Observables)发出的项。

1 buffer 缓冲区

将 reactive source发出的项收集到缓冲区中,并发出这些缓冲区

Observable.range(0, 10)
    .buffer(4)
    .subscribe((List<Integer> buffer) -> System.out.println(buffer));

输出

[0, 1, 2, 3]
[4, 5, 6, 7]
[8, 9]

2 cast 类型转换

将reactive source发出的每个项转换为指定的类型,并发出这些项。

Observable<Number> numbers = Observable.just(1, 4.0, 3f, 7, 12, 4.6, 5);

numbers.filter((Number x) -> Integer.class.isInstance(x))
    .cast(Integer.class)
    .subscribe((Integer x) -> System.out.println(x));

输出

1
7
12
5

3 concatMap 并行map操作并concat合并

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,其中,该函数返回一个reactive source,并发出连接这些函数应用程序的结果所产生的项。

Observable.range(0, 5)
    .concatMap(i -> {
        long delay = Math.round(Math.random() * 2);

        return Observable.timer(delay, TimeUnit.SECONDS).map(n -> i);
    })
    .blockingSubscribe(System.out::print);

输出

01234

4 concatMapCompletable

将给定的io.reactivex.functions.Function应用于由 reactive source发出的每个项,该函数返回io.reactivex.CompletableSource,一次订阅一个,并返回一个complete,该complete在所有源完成时完成。

Observable<Integer> source = Observable.just(2, 1, 3);
Completable completable = source.concatMapCompletable(x -> {
    return Completable.timer(x, TimeUnit.SECONDS)
        .doOnComplete(() -> System.out.println("Info: Processing of item \"" + x + "\" completed"));
    });

completable.doOnComplete(() -> System.out.println("Info: Processing of all items completed"))
    .blockingAwait();

输出

Info: Processing of item "2" completed Info: Processing of item "1" completed Info: Processing of item "3" completed Info: Processing of all items completed

5 concatMapCompletableDelayError

将给定的io.reactivex.functions.Function应用于由reactive source,发出的每个项,该函数返回io.reactivex.CompletableSource,一次订阅一个源,并返回一个complete,该complete在所有源完成时完成。源的任何错误都将被延迟,直到所有错误都终止。

Observable<Integer> source = Observable.just(2, 1, 3);
Completable completable = source.concatMapCompletableDelayError(x -> {
    if (x.equals(2)) {
        return Completable.error(new IOException("Processing of item \"" + x + "\" failed!"));
    } else {
        return Completable.timer(1, TimeUnit.SECONDS)
            .doOnComplete(() -> System.out.println("Info: Processing of item \"" + x + "\" completed"));
    }
});

completable.doOnError(error -> System.out.println("Error: " + error.getMessage()))
    .onErrorComplete()
    .blockingAwait();

输出

Info: Processing of item "1" completed Info: Processing of item "3" completed Error: Processing of item "2" failed!

6 concatMapDelayError

将给定的io.reactivex.functions.Function应用于由无 reactive source,发出的每个项,其中该函数返回一个 reactive source,并发出连接这些函数应用程序的结果所产生的项。源的任何错误都将被延迟,直到所有错误都终止。

Observable.intervalRange(1, 3, 0, 1, TimeUnit.SECONDS)
    .concatMapDelayError(x -> {
        if (x.equals(1L)) return Observable.error(new IOException("Something went wrong!"));
        else return Observable.just(x, x * x);
    })
    .blockingSubscribe(
        x -> System.out.println("onNext: " + x),
        error -> System.out.println("onError: " + error.getMessage()));

输出

onNext: 2 onNext: 4 onNext: 3 onNext: 9 onError: Something went wrong!

7 concatMapEager

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,函数返回一个reactive source,并发出连接这些函数应用程序的结果所产生的项。与concatMap不同的是,这个操作符急切地订阅所有源。

Observable.range(0, 5)
                .concatMapEager(i -> {
                    long delay = Math.round(Math.random() * 3);
                    System.out.println("delay:" + delay+"\ti:"+i);
                    return Observable.timer(delay, TimeUnit.SECONDS)
                            .map(n -> {
                                System.out.println("n:" + n + "\ti:" + i);
                                return i;
                            })
                            .doOnNext(x -> System.out.println("Info: Finished processing item " + x));
                })
                .blockingSubscribe(i -> System.out.println("onNext: " + i));

delay:1 i:0 delay:1 i:1 delay:2 i:2 delay:2 i:3 delay:2 i:4 n:0 i:1 n:0 i:0 Info: Finished processing item 0 Info: Finished processing item 1 onNext: 0 onNext: 1 n:0 i:4 n:0 i:2 n:0 i:3 Info: Finished processing item 2 Info: Finished processing item 4 onNext: 2 Info: Finished processing item 3 onNext: 3 onNext: 4

8 concatMapEagerDelayError

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,函数返回一个reactive source,并发出连接这些函数应用程序的结果所产生的项。必须指定布尔值,如果为真,表明所有来源的所有错误将被延迟到最后,否则,如果为false,当前源终止时,将发出来自主源的错误信号。与concatMapDelayError不同的是,这个操作符急切地订阅所有源。

Observable<Integer> source = Observable.create(emitter -> {
    emitter.onNext(1);
    emitter.onNext(2);
    emitter.onError(new Error("Fatal error!"));
});

source.doOnError(error -> System.out.println("Info: Error from main source " + error.getMessage()))
    .concatMapEagerDelayError(x -> {
        return Observable.timer(1, TimeUnit.SECONDS).map(n -> x)
            .doOnSubscribe(it -> System.out.println("Info: Processing of item \"" + x + "\" started"));
    }, true)
    .blockingSubscribe(
        x -> System.out.println("onNext: " + x),
        error -> System.out.println("onError: " + error.getMessage()));

输出

Info: Processing of item "1" started Info: Processing of item "2" started Info: Error from main source Fatal error! onNext: 1 onNext: 2 onError: Fatal error!

9 concatMapIterable

将给定的io.reactivex.functions.Function应用于由reactive source,发出的每个项,该函数返回一个java.lang.Iterable,并发出连接这些函数应用程序的结果所产生的项。

Observable.just("A", "B", "C")
    .concatMapIterable(item -> List.of(item, item, item))
    .subscribe(System.out::print);

输出

AAABBBCCC

10 concatMapMaybe

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,该函数返回io.reactivex.MaybeSource,并发出连接这些MaybeSources所产生的项。

Observable.just("5", "3,14", "2.71", "FF")
    .concatMapMaybe(v -> {
        return Maybe.fromCallable(() -> Double.parseDouble(v))
            .doOnError(e -> System.out.println("Info: The value \"" + v + "\" could not be parsed."))

            // Ignore values that can not be parsed.
            .onErrorComplete();
    })
    .subscribe(x -> System.out.println("onNext: " + x));

onNext: 5.0 Info: The value "3,14" could not be parsed. onNext: 2.71 Info: The value "FF" could not be parsed.

11 concatMapMaybeDelayError

将给定的io.reactivex.functions.Function应用于由响应源发出的每个项,其中该函数返回一个io.reactivex.MaybeSource,并发出连接这些MaybeSources所产生的项。源的任何错误都将被延迟,直到所有错误都终止。

DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd.MM.uuuu");
Observable.just("04.03.2018", "12-08-2018", "06.10.2018", "01.12.2018")
    .concatMapMaybeDelayError(date -> {
        return Maybe.fromCallable(() -> LocalDate.parse(date, dateFormatter));
    })
    .subscribe(
        localDate -> System.out.println("onNext: " + localDate),
        error -> System.out.println("onError: " + error.getMessage()));

输出

onNext: 2018-03-04 onNext: 2018-10-06 onNext: 2018-12-01 onError: Text '12-08-2018' could not be parsed at index 2

12 concatMapSingle

将给定的io.reactivex.functions.Function应用于由 reactive source发出的每个项,该函数返回io.reactivex.SingleSource,并发出连接这些' ' SingleSource ' '的结果项。

Observable.just("5", "3,14", "2.71", "FF")
    .concatMapSingle(v -> {
        return Single.fromCallable(() -> Double.parseDouble(v))
            .doOnError(e -> System.out.println("Info: The value \"" + v + "\" could not be parsed."))

            // Return a default value if the given value can not be parsed.
            .onErrorReturnItem(42.0);
    })
    .subscribe(x -> System.out.println("onNext: " + x));

输出

onNext: 5.0 Info: The value "3,14" could not be parsed. onNext: 42.0 onNext: 2.71 Info: The value "FF" could not be parsed. onNext: 42.0

13 concatMapSingleDelayError

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,该函数返回io.reactivex.SingleSource,并发出连接这些函数应用程序的结果所产生的项。源的任何错误都将被延迟,直到所有错误都终止。

DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd.MM.uuuu");
Observable.just("24.03.2018", "12-08-2018", "06.10.2018", "01.12.2018")
    .concatMapSingleDelayError(date -> {
        return Single.fromCallable(() -> LocalDate.parse(date, dateFormatter));
    })
    .subscribe(
        localDate -> System.out.println("onNext: " + localDate),
        error -> System.out.println("onError: " + error.getMessage()));

输出

// onNext: 2018-03-24
// onNext: 2018-10-06
// onNext: 2018-12-01
// onError: Text '12-08-2018' could not be parsed at index 2

14 flatMap

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,函数返回一个reactive source,并发出合并这些函数应用程序的结果所产生的项。

 Observable.just("A", "B", "C")
                .flatMap(a -> {
                    System.out.println("a:"+a);
                    return Observable.intervalRange(1, 3, 0, 1, TimeUnit.SECONDS)
                            .map(b -> {
                                System.out.println("a:"+a+"\tb:"+b);
                                return '(' + a + ", " + b + ')';
                            });
                })
                .blockingSubscribe(System.out::println);

不一定是这个顺序

a:A
a:B
a:C
a:A	b:1
a:B	b:1
a:C	b:1
(A, 1)
(B, 1)
(C, 1)
a:A	b:2
a:B	b:2
a:C	b:2
(A, 2)
(B, 2)
(C, 2)
a:A	b:3
a:C	b:3
(A, 3)
(C, 3)
a:B	b:3
(B, 3)

15 flatMapCompletable

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,该函数返回io.reactivex.CompletableSource,

并返回一个complete,该complete在所有源完成时完成。

Observable<Integer> source = Observable.just(2, 1, 3);
Completable completable = source.flatMapCompletable(x -> {
    return Completable.timer(x, TimeUnit.SECONDS)
        .doOnComplete(() -> System.out.println("Info: Processing of item \"" + x + "\" completed"));
});

completable.doOnComplete(() -> System.out.println("Info: Processing of all items completed"))
    .blockingAwait();

输出

// Info: Processing of item "1" completed
// Info: Processing of item "2" completed
// Info: Processing of item "3" completed
// Info: Processing of all items completed

16 flatMapIterable

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,该函数返回java.lang.Iterable,并从这些Iterables中发出元素。

Observable.just(1, 2, 3, 4)
    .flatMapIterable(x -> {
        switch (x % 4) {
            case 1:
                return List.of("A");
            case 2:
                return List.of("B", "B");
            case 3:
                return List.of("C", "C", "C");
            default:
                return List.of();
        }
    })
    .subscribe(System.out::println);

输出

// A
// B
// B
// C
// C
// C

17 flatMapMaybe

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,该函数返回io.reactivex.MaybeSource,并发出合并这些MaybeSource而产生的项。

Observable.just(9.0, 16.0, -4.0)
    .flatMapMaybe(x -> {
        if (x.compareTo(0.0) < 0) return Maybe.empty();
        else return Maybe.just(Math.sqrt(x));
    })
    .subscribe(
        System.out::println,
        Throwable::printStackTrace,
        () -> System.out.println("onComplete"));

输出

// 3.0
// 4.0
// onComplete

18 flatMapObservable

将给定的io.reactivex.functions.Function应用于由Maybe或Single发出的项,该函数返回io.reactivex.ObservableSource,并返回一个Observable,该Observable会发出由这个ObservableSource发出的项。

Single<String> source = Single.just("Kirk, Spock, Chekov, Sulu");
Observable<String> names = source.flatMapObservable(text -> {
    return Observable.fromArray(text.split(","))
            .map(String::strip);
});

names.subscribe(name -> System.out.println("onNext: " + name));

输出

// onNext: Kirk
// onNext: Spock
// onNext: Chekov
// onNext: Sulu

19 flatMapPublisher

将给定的io.reactivex.functions.Function应用于由Maybe或Single发出的项,该函数返回一个org.reactivestreams.Publisher,并返回一个Flowable,该Flowable会发出由该Publisher发出的项。

Single<String> source = Single.just("Kirk, Spock, Chekov, Sulu");
Flowable<String> names = source.flatMapPublisher(text -> {
    return Flowable.fromArray(text.split(","))
            .map(String::strip);
});

names.subscribe(name -> System.out.println("onNext: " + name));

输出

 onNext: Kirk
// onNext: Spock
// onNext: Chekov
// onNext: Sulu

20 flatMapSingle

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,该函数返回io.reactivex.SingleSource,并发出合并这些SingleSource而产生的项。

Observable.just(4, 2, 1, 3)
    .flatMapSingle(x -> Single.timer(x, TimeUnit.SECONDS).map(i -> x))
    .blockingSubscribe(System.out::print);

输出

1234

注意:如果Maybe源为空,flatMapSingle返回一个发出错误通知的Single:

Maybe<Object> emptySource = Maybe.empty();
Single<Object> result = emptySource.flatMapSingle(x -> Single.just(x));
result.subscribe(
    x -> System.out.println("onSuccess will not be printed!"),
    error -> System.out.println("onError: Source was empty!"));

输出

onError: Source was empty!

21 flatMapSingleElement

将给定的io.reactivex.functions.Function应用到由Maybe,该函数返回io.reactivex.SingleSource,并返回一个Maybe,它要么发出由SingleSource发出的项,要么在源Maybe刚刚完成时完成。

Maybe<Integer> source = Maybe.just(-42);
Maybe<Integer> result = source.flatMapSingleElement(x -> {
    return Single.just(Math.abs(x));
});

result.subscribe(System.out::println);

输出

42

22 flattenAsFlowable

将给定的io.reactivex.functions.Function应用于由Maybe或Single发出的项,该函数返回java.lang.Iterable,并返回一个可观察对象,该可观察对象发出来自这个可迭代对象的元素。

Single<Double> source = Single.just(2.0);
Flowable<Double> flowable = source.flattenAsFlowable(x -> {
    return List.of(x, Math.pow(x, 2), Math.pow(x, 3));
});

flowable.subscribe(x -> System.out.println("onNext: " + x));

输出

// onNext: 2.0
// onNext: 4.0
// onNext: 8.0

23 flattenAsObservable

将给定的io.reactivex.functions.Function应用于由Maybe或Single发出的项,该函数返回java.lang.Iterable,并返回一个可观察对象,该可观察对象发出来自这个可迭代对象的元素。

Single<Double> source = Single.just(2.0);
Observable<Double> observable = source.flattenAsObservable(x -> {
    return List.of(x, Math.pow(x, 2), Math.pow(x, 3));
});

observable.subscribe(x -> System.out.println("onNext: " + x));

输出

// onNext: 2.0
// onNext: 4.0
// onNext: 8.0

24 groupBy

根据指定的标准对reactive source发出的项目进行分组,并将这些分组项作为groupedoobservable或GroupedFlowable发出。

Observable<String> animals = Observable.just(
    "Tiger", "Elephant", "Cat", "Chameleon", "Frog", "Fish", "Turtle", "Flamingo");

animals.groupBy(animal -> animal.charAt(0), String::toUpperCase)
    .concatMapSingle(Observable::toList)
    .subscribe(System.out::println);

输出

// [TIGER, TURTLE]
// [ELEPHANT]
// [CAT, CHAMELEON]
// [FROG, FISH, FLAMINGO]

24 map

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,并发出这些函数应用的结果。

Observable.just(1, 2, 3)
    .map(x -> x * x)
    .subscribe(System.out::println);

输出

// 1
// 4
// 9

25 scan

将给定的io.reactivex.functions.BiFunction应用到一个种子值和reactive source发出的第一项,然后将该函数应用程序的结果以及reactive source发出的第二项输入到同一个函数中,如此类推,直到所有项目都被reactive source发射,发射每个中间结果。

Observable.just(5, 3, 8, 1, 7)
    .scan(0, (partialSum, x) -> partialSum + x)
    .subscribe(System.out::println);
输出
// 0
// 5
// 8
// 16
// 17
// 24

26 switchMap

将给定的io.reactivex.functions.Function应用于由reactive source发出的每个项,其中,该函数返回一个reactive source,并发出由这些reactive source最近投射的项目。

Observable.interval(0, 1, TimeUnit.SECONDS)
    .switchMap(x -> {
        return Observable.interval(0, 750, TimeUnit.MILLISECONDS)
                .map(y -> x);
    })
    .takeWhile(x -> x < 3)
    .blockingSubscribe(System.out::print);

输出

001122

26 window

收集由 reactive source发出的项目到窗口中,并将这些窗口作为一个流动或可观察对象发出。

Observable.range(1, 10)

    // Create windows containing at most 2 items, and skip 3 items before starting a new window.
    //创建最多包含2项的窗口,并在启动新窗口之前跳过3项。
    .window(2, 3)
    .flatMapSingle(window -> {
        return window.map(String::valueOf)
                .reduce(new StringJoiner(", ", "[", "]"), StringJoiner::add);
    })
    .subscribe(System.out::println);

输出

// [1, 2]
// [4, 5]
// [7, 8]
// [10]