RxJava-2-0还没熟悉,RxJava-3-0说来就来了!(多种操作符代码详解篇)

本文详细介绍了RxJava中的一系列操作符,包括流的切片(skip,skipLast)、去抖(debounce)、去重(distinct,distinctUntilChanged)、元素访问(elementAt,elementAtOrError)、过滤(filter)、获取首尾元素(first,last,firstOrDefault,lastOrDefault,firstOrError,lastOrError)、忽略元素(ignoreElements)、采样(sample)、连接操作符(startWith,merge,zip,combineLatest)以及变换操作符(buffer,cast,concatMap,concatMapDelayError)。
摘要由CSDN通过智能技术生成

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

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

打印结果:5678910

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

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

打印结果:1 2 3 4 5 6

skipLast(n)操作表示从流的尾部跳过n个元素。

2、debounce(去抖动)

可作用于Flowable,Observable。在Android开发,通常为了防止用户重复点击而设置标记位,而通过RxJava的debounce操作符可以有效达到该效果。在规定时间内,用户重复点击只有最后一次有效,

Observable 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.print(item+" "),
Throwable::printStackTrace,
() -> System.out.println(“onComplete”));

打印:A D E onComplete

上文代码中,数据源以一定的时间间隔发送A,B,C,D,E。操作符debounce的时间设为1秒,发送A后1.5秒并没有发射其他数据,所以A能成功发射。发射B后,在1秒之内,又发射了C和D,在D之后的2秒才发射E,所有B、C都失效,只有D有效;而E之后已经没有其他数据流了,所有E有效。

3、distinct(去重)

可作用于Flowable,Observable,去掉数据源重复的数据。

Observable.just(2, 3, 4, 4, 2, 1)
.distinct()
.subscribe(System.out::print);

// 打印:2 3 4 1
Observable.just(1, 1, 2, 1, 2, 3, 3, 4)
.distinctUntilChanged()
.subscribe(System.out::print);
//打印:1 2 1 2 3 4

distinctUntilChanged()去掉相邻重复数据。

4、elementAt(获取指定位置元素)

可作用于Flowable,Observable,从数据源获取指定位置的元素,从0开始。

Observable.just(2,4,3,1,5,8)
.elementAt(0)
.subscribe(integer ->
Log.d(“TAG”,“elmentAt->”+integer));
打印:2

Observable source = Observable.just(“Kirk”, “Spock”, “Chekov”, “Sulu”);
Single element = source.elementAtOrError(4);

element.subscribe(
name -> System.out.println(“onSuccess will not be printed!”),
error -> System.out.println("onError: " + error));
打印:onSuccess will not be printed!

elementAtOrError:指定元素的位置超过数据长度,则发射异常。

5、filter(过滤)

可作用于 Flowable,Observable,Maybe,Single。在filter中返回表示发射该元素,返回false表示过滤该数据。

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

6、first(第一个)

作用于 Flowable,Observable。发射数据源第一个数据,如果没有则发送默认值。

Observable source = Observable.just(“A”, “B”, “C”);
Single firstOrDefault = source.first(“D”);
firstOrDefault.subscribe(System.out::println);
打印:A

Observable emptySource = Observable.empty();
Single firstOrError = emptySource.firstOrError();
firstOrError.subscribe(
element -> System.out.println(“onSuccess will not be printed!”),
error -> System.out.println("onError: " + error));
打印:onError: java.util.NoSuchElementException

和firstElement的区别是first返回的是Single,而firstElement返回Maybe。firstOrError在没有数据会返回异常。

7、last(最后一个)

last、lastElement、lastOrError与fist、firstElement、firstOrError相对应。

Observable source = Observable.just(“A”, “B”, “C”);
Single lastOrDefault = source.last(“D”);
lastOrDefault.subscribe(System.out::println);
//打印:C

Observable source = Observable.just(“A”, “B”, “C”);
Maybe last = source.lastElement();
last.subscribe(System.out::println);
//打印:C

Observable emptySource = Observable.empty();
Single lastOrError = emptySource.lastOrError();
lastOrError.subscribe(
element -> System.out.println(“onSuccess will not be printed!”),
error -> System.out.println("onError: " + error));
// 打印:onError: java.util.NoSuchElementException

8、ignoreElements & ignoreElement(忽略元素)

ignoreElements 作用于Flowable、Observable。ignoreElement作用于Maybe、Single。两者都是忽略掉数据,返回完成或者错误时间。

Single source = Single.timer(1, TimeUnit.SECONDS);
Completable completable = source.ignoreElement();
completable.doOnComplete(() -> System.out.println(“Done!”))
.blockingAwait();
// 1秒后打印:Donde!

Observable source = Observable.intervalRange(1, 5, 1, 1, TimeUnit.SECONDS);
Completable completable = source.ignoreElements();
completable.doOnComplete(() -> System.out.println(“Done!”))
.blockingAwait();
// 五秒后打印:Done!

9、ofType(过滤掉类型)

作用于Flowable、Observable、Maybe、过滤掉类型。

Observable numbers = Observable.just(1, 4.0, 3, 2.71, 2f, 7);
Observable integers = numbers.ofType(Integer.class);
integers.subscribe((Integer x) -> System.out.print(x+" "));
//打印:1 3 7

10、sample

作用于Flowable、Observable,在一个周期内发射最新的数据。

Observable 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.print(item+" "),
Throwable::printStackTrace,
() -> System.out.print(“onComplete”));

// 打印: C D onComplete

与debounce的区别是,sample是以时间为周期的发射,一秒又一秒内的最新数据。而debounce是最后一个有效数据开始。

11、throttleFirst & throttleLast & throttleWithTimeout

作用于Flowable、Observable。throttleLast与smaple一致,而throttleFirst是指定周期内第一个数据。throttleWithTimeout与debounce一致。

Observable 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.print(item+" “),
Throwable::printStackTrace,
() -> System.out.print(” onComplete"));
//打印:A D onComplete

source.subscribeOn(Schedulers.io())
.throttleLast(1, TimeUnit.SECONDS)
.blockingSubscribe(
item -> System.out.print(item+" “),
Throwable::printStackTrace,
() -> System.out.print(” onComplete"));

// 打印:C D onComplete

12、throttleLatest

之所以拿出来单独说,我看不懂官网的解释。然后看别人的文章:throttleFirst+throttleLast的组合?开玩笑的吧。个人理解是:如果源的第一个数据总会被发射,然后开始周期计时,此时的效果就会跟throttleLast一致。

Observable source = Observable.create(emitter -> {
emitter.onNext(“A”);

Thread.sleep(500);
emitter.onNext(“B”);

Thread.sleep(200);
emitter.onNext(“C”);

Thread.sleep(200);
emitter.onNext(“D”);

Thread.sleep(400);
emitter.onNext(“E”);

Thread.sleep(400);
emitter.onNext(“F”);

Thread.sleep(400);
emitter.onNext(“G”);

Thread.sleep(2000);
emitter.onComplete();
});
source.subscribeOn(Schedulers.io())
.throttleLatest(1, TimeUnit.SECONDS)
.blockingSubscribe(
item -> Log.e(“RxJava”,item),
Throwable::printStackTrace,
() -> Log.e(“RxJava”,“finished”));

打印结果:

13、take & takeLast

作用于Flowable、Observable,take发射前n个元素;takeLast发射后n个元素。

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

source.take(4)
.subscribe(System.out::print);
//打印:1 2 3 4

source.takeLast(4)
.subscribe(System.out::println);
//打印:7 8 9 10

14、timeout(超时)

作用于Flowable、Observable、Maybe、Single、Completabl。后一个数据发射未在前一个元素发射后规定时间内发射则返回超时异常。

Observable 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.

连接操作符

通过连接操作符,将多个被观察数据(数据源)连接在一起。

1、startWith

可作用于Flowable、Observable。将指定数据源合并在另外数据源的开头。

Observable names = Observable.just(“Spock”, “McCoy”);
Observable otherNames = Observable.just(“Git”, “Code”,“8”);
names.startWith(otherNames).subscribe(item -> Log.d(TAG,item));

//打印:
RxJava: Git
RxJava: Code
RxJava: 8
RxJava: Spock
RxJava: McCo

2、merge

可作用所有数据源类型,用于合并多个数据源到一个数据源。

Observable names = Observable.just(“Hello”, “world”);
Observable otherNames = Observable.just(“Git”, “Code”,“8”);

Observable.merge(names,otherNames).subscribe(name -> Log.d(TAG,name));

//也可以是
//names.mergeWith(otherNames).subscribe(name -> Log.d(TAG,name));

//打印:
RxJava: Hello
RxJava: world
RxJava: Git
RxJava: Code
RxJava: 8

merge在合并数据源时,如果一个合并发生异常后会立即调用观察者的onError方法,并停止合并。可通过mergeDelayError操作符,将发生的异常留到最后处理。

Observable names = Observable.just(“Hello”, “world”);
Observable otherNames = Observable.just(“Git”, “Code”,“8”);
Observable error = Observable.error(
new NullPointerException(“Error!”));
Observable.mergeDelayError(names,error,otherNames).subscribe(
name -> Log.d(TAG,name), e->Log.d(TAG,e.getMessage()));

//打印:
RxJava: Hello
RxJava: world
RxJava: Git
RxJava: Code
RxJava: 8
RxJava: Error!

3、zip

可作用于Flowable、Observable、Maybe、Single。将多个数据源的数据一个一个的合并在一起哇。当其中一个数据源发射完事件之后,若其他数据源还有数据未发射完毕,也会停止。

Observable names = Observable.just(“Hello”, “world”);
Observable otherNames = Observable.just(“Git”, “Code”, “8”);
names.zipWith(otherNames, (first, last) -> first + “-” + last)
.subscribe(item -> Log.d(TAG, item));

//打印:
RxJava: Hello-Git
RxJava: world-Code

4、combineLatest

可作用于Flowable, Observable。在结合不同数据源时,发射速度快的数据源最新item与较慢的相结合。 如下时间线,Observable-1发射速率快,发射了65,Observable-2才发射了C, 那么两者结合就是C5。

5、switchOnNext

一个发射多个小数据源的数据源,这些小数据源发射数据的时间发生重复时,取最新的数据源。

变换操作符

变化数据源的数据,并转化为新的数据源。

1、buffer

作用于Flowable、Observable。指将数据源拆解含有长度为n的list的多个数据源,不够n的成为一个数据源。

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

// 打印:
// [0, 1, 2, 3]
// [4, 5, 6, 7]
// [8, 9]

2、cast

作用于Flowable、Observable、Maybe、Single。将数据元素转型成其他类型,转型失败会抛出异常。

Observable 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));
// prints:
// 1
// 7
// 12
// 5

3、concatMap

作用于Flowable、Observable、Maybe。将数据源的元素作用于指定函数后,将函数的返回值有序的存在新的数据源。

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);

// prints 01234

4、concatMapDelayError

与concatMap作用相同,只是将过程发送的所有错误延迟到最后处理。

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()));

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

5、concatMapCompletable

作用于Flowable、Observable。与contactMap类似,不过应用于函数后,返回的是CompletableSource。订阅一次并在所有CompletableSource对象完成时返回一个Completable对象。

Observable 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();

// prints:
// Info: Processing of item “2” completed
// Info: Processing of item “1” completed
// Info: Processing of item “3” completed
// Info: Processing of all items completed

6、concatMapCompletableDelayError

与concatMapCompletable作用相同,只是将过程发送的所有错误延迟到最后处理。

Observable 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();

// prints:
// Info: Processing of item “1” completed
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

文末

面试:如果不准备充分的面试,完全是浪费时间,更是对自己的不负责!

不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

e-1711900518296)]

[外链图片转存中…(img-RIOaO8Di-1711900518296)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

文末

面试:如果不准备充分的面试,完全是浪费时间,更是对自己的不负责!

不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值