【Rxjava详解】(二) 操作符的妙用

文章目录

    • 接口变化
    • 操作符
      • map
      • flatmap
      • debounce
      • throttleFirst()
      • take
      • concat

RxJava 是一个基于 观察者模式的异步编程库,它提供了丰富的操作符来处理和转换数据流。 操作符是 RxJava 的核心组成部分,它们提供了一种灵活、可组合的方式来处理数据流,使得开发者可以更加便捷地进行数据处理和流程控制。

接口变化

RxJava 2.x拥有了新的特性,其依赖于4个接口:

  • Publisher
  • Subscriber
  • Subscription
  • Processor
  1. SubscriberFunc1变为Function等等。此外,还引入了SingleMaybeCompletable等新的可观察类型。
  2. RxJava 2.x 中的背压支持:RxJava 2.x 引入了对背压的支持,新增了Flowable类型来处理背压场景。同时,对一些操作符的行为进行了一些修改以适应背压机制。
  3. 异常处理方式的变化:在RxJava 1.x中,异常处理是通过onError()方法来处理,而在RxJava 2.x中,引入了onError(Throwable)方法和onError(Throwable, boolean)方法,允许开发者控制是否中断流程。
  4. 取消订阅的方式变化:在RxJava 1.x中,使用unsubscribe()方法取消订阅,而在RxJava 2.x中,使用dispose()方法取消订阅

关于背压:

在RxJava中,背压(Backpressure)是一种处理生产者和消费者之间速度不匹配的机制。通过背压,可以使得消费者根据自身的处理能力告知生产者它们能够接受的数据量,从而避免生产者产生过多的数据导致消费者无法处理的情况。

而在RxJava 2.x ~ RxJava 3.x,发生以下变化:

  • 不再支持Backpressure:RxJava 3.x不再内置支持背压机制,而是采用基于Reactive-Streams的响应式规范,并提供了相应的Flowable类型。因此,在RxJava 3.x中,需要使用Flowable来处理背压场景。
  • Observer接口的变化:在RxJava 3.x中,Observer接口被拆分为两个接口:ObserverDisposableObserver接口用于处理事件的消费,而Disposable接口用于取消订阅。
  • SingleObserverCompletableObserver的变化:在RxJava 3.x中,SingleObserverCompletableObserver接口的方法签名有所变化,取消订阅的方法从dispose()改为了onDispose()

操作符

RxJava提供了对事件序列进行变换的支持,这是它的核心功能之一.所谓变换,就是将事件序列中的对象或整个序列进行加工处理,转换成不同的事件或事件序列。
操作符是用来对Observable(或Flowable)流进行转换、过滤、组合和操作的方法。

RxJava提供了很多很有用的操作符。多的要死
在Rxjava 3.x 下,有以下常见的操作符:

  1. map:将Observable发射的数据项通过指定的函数进行转换,并发射转换后的数据项。
  2. filter:根据指定的条件过滤Observable发射的数据项,只发射满足条件的数据项。
  3. take:只发射Observable发射的前N个数据项,忽略后面的数据项。
  4. skip:跳过Observable发射的前N个数据项,只发射后面的数据项。
  5. merge:将多个Observable合并成一个Observable,按照时间顺序发射合并后的数据项。
  6. zip:将多个Observable按照顺序进行合并,每个数据项都是由对应位置的Observable发射的数据项组合而成。
  7. concat:按照顺序连接多个Observable,依次发射它们的数据项,等前一个Observable完成后才会订阅下一个Observable。
  8. onErrorResumeNext:在Observable发生错误时,使用备用的Observable继续发射数据项。
  9. retry:在Observable发生错误时,进行错误重试,重新订阅Observable。
  10. interval:创建一个按照固定时间间隔发射递增数值的Observable。
  11. debounce:只有在指定的时间间隔内没有发射新的数据项时,才发射最后一个数据项。
  12. distinct:过滤掉重复的数据项,只发射不重复的数据项。
  13. flatMap:将Observable发射的数据项转换为Observable集合,并按顺序发射这些Observable发射的数据项。
  14. reduce:对Observable发射的数据项进行累积操作,返回最终的累积结果。
  15. scan:对Observable发射的数据项进行累积操作,并按顺序发射每次累积的结果

在此简单介绍其中几个的用法:

map

示意图:

image.png

实际上,map操作符可以理解为对Observable发射的每个数据项都应用一个函数,将原始数据项转换为另一种形式的数据项,然后再发射出去。(感觉Kotlin里有)

假设我们有一个Observable发射的是整数序列,我们想将每个整数乘以2,并发射出去。

Observable<Integer> observable = Observable.just(1, 2, 3, 4, 5);observable.map(number -> number * 2).subscribe(result -> System.out.println(result));输出:
2
4
6
8
10

flatmap

flatMap操作符会对Observable的每个数据项应用一个函数,这个函数返回一个新的Observable。然后,它会将这些新的Observable合并成一个Observable,并发射合并后的数据项。

假设我们有一个Observable发射的是字符串数组,我们想将每个字符串拆分为字符数组,并发射出去。

Observable<String> observable = Observable.just("Hello", "World", "RxJava");observable.flatMap(str -> Observable.fromArray(str.split(""))).subscribe(character -> System.out.print(character + " "));

输出:

H e l l o W o r l d R x J a v a

flatMap操作符将每个字符串拆分为字符数组,并将所有的字符合并成了一个Observable,最终发射出去。

debounce

debounce操作符也是RxJava中常用的操作符之一,它用于在一定时间间隔内只发射最后一个数据项,忽略中间的数据项。debounce操作符主要用于处理需要在一定时间内连续发生的事件,但只关心最后一个事件的场景。

在安卓开发中,debounce操作符可以用于处理用户输入场景,比如搜索框输入关键词时,通常需要等待用户停止输入一段时间后再进行搜索,以减少不必要的网络请求。

Observable<String> observable = Observable.create(emitter -> {editText.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic void afterTextChanged(Editable s) {emitter.onNext(s.toString());}});
});observable.debounce(500, TimeUnit.MILLISECONDS).subscribe(keyword -> {// 进行搜索操作performSearch(keyword);});

我们首先创建了一个Observable对象,该Observable通过监听EditText的文本变化事件,将用户输入的关键词发射出去。

然后,我们使用debounce操作符,设置一个时间间隔(这里是500毫秒),它会在用户输入停止500毫秒后才发射最后一个关键词。

最后,通过subscribe方法订阅Observable,并在订阅中执行搜索操作。

这样做的好处是,用户在连续输入时,debounce操作符会忽略中间的输入,只关注最后一个输入,在用户停止输入一段时间后才执行搜索操作,避免不必要的网络请求。

throttleFirst()

throttleFirst()操作符也是RxJava中常用的操作符之一,它用于在指定时间间隔内只发射第一个数据项,忽略后续的数据项。throttleFirst操作符主要用于处理需要限制触发频率的事件,保证在指定时间间隔内只处理一次。

在安卓开发中,throttleFirst操作符可以用于处理按钮点击事件,防止用户重复点击按钮造成重复操作:

Observable<Object> observable = Observable.create(emitter -> {button.setOnClickListener(v -> {emitter.onNext(new Object());});
});observable.throttleFirst(1000, TimeUnit.MILLISECONDS).subscribe(event -> {// 执行按钮点击操作ClickAction();});

take

take()操作符也是RxJava中常用的操作符之一,用于从Observable中取出一定数量的数据项,并在达到指定数量后停止发射。它可以与Retrofit和RxJava的线程切换一起使用,来控制网络请求结果的数量和线程切换。

在安卓开发中,通常使用Retrofit进行网络请求,而结合RxJava可以实现异步操作和线程切换。下面是一个结合Retrofit和RxJava的实例,使用take操作符来限制结果数量,并配合线程切换:

首先,创建一个网络请求的接口:

public interface ApiInterface {@GET("data")Observable<List<Data>> getData();
}

然后,创建一个Retrofit实例,并结合RxJava的Observable进行网络请求:

ApiInterface apiInterface = RetrofitClient.getClient().create(ApiInterface.class);apiInterface.getData().subscribeOn(Schedulers.io()) // 在IO线程进行网络请求.observeOn(AndroidSchedulers.mainThread()) // 在主线程接收和处理结果.take(5) // 只接收前5个数据项.subscribe(dataList -> {// 处理获取到的数据for (Data data : dataList) {Log.d(TAG, "Received data: " + data.toString());}}, throwable -> {// 处理错误Log.e(TAG, "Error: " + throwable.getMessage());});

先建了一个ApiInterface的实例,用于定义网络接口。

然后用Retrofit和RxJava的Observable结合进行网络请求。通过subscribeOn()方法指定在IO线程进行网络请求,observeOn()方法指定在主线程接收和处理结果。使用take(5)操作符来限制只接收前5个数据项,即结果数量限制为5。

最后,通过subscribe方法订阅Observable,并在订阅中处理获取到的数据或错误。

concat

concat()操作符是RxJava中常用的操作符之一,用于将多个Observable按顺序连接在一起,并依次发射数据。它可以在安卓开发中用于实现多个下载任务的顺序执行。

在安卓开发中,有时需要进行多个文件的下载操作,可以使用concat操作符来依次执行下载任务:

创建一个下载任务的接口:

public interface DownloadService {@GETObservable<ResponseBody> downloadFile(@Url String fileUrl);
}

Retrofit结合RxJava的Observable进行下载任务:

DownloadService service = RetrofitClient.getClient().create(DownloadService.class);Observable<ResponseBody> downloadTask1 = service.downloadFile("http://example.com/file1");
Observable<ResponseBody> downloadTask2 = service.downloadFile("http://example.com/file2");
Observable<ResponseBody> downloadTask3 = service.downloadFile("http://example.com/file3");Observable.concat(downloadTask1, downloadTask2, downloadTask3).subscribeOn(Schedulers.io()) // 在IO线程进行下载任务.observeOn(AndroidSchedulers.mainThread()) // 在主线程接收和处理结果.subscribe(responseBody -> {// 处理下载完成的文件saveFile(responseBody);}, throwable -> {// 处理错误Log.e(TAG, "Error: " + throwable.getMessage());});

操作符真的很多,其他的可以看详细文档进行转换,学习RxJava的操作符的关键是理解其原理和使用场景,以及熟悉常用的操作符和它们的功能。

操作符可以总结为以下几种:

  1. 转换操作符:用来对数据进行转换,比如将一个数据类型转换成另一个数据类型,或者对数据进行映射或扁平化处理。
  2. 过滤操作符:用来过滤数据流中的元素,比如只保留满足特定条件的元素,或者去除重复的元素。
  3. 组合操作符:用来将多个数据流进行组合,比如将多个流依次连接在一起,或者合并多个流的元素。
  4. 错误处理操作符:用来处理异常和错误情况,比如在遇到错误时返回一个默认值,或者在错误发生时切换到另一个数据流。
  5. 调度操作符:用来控制数据流在不同线程之间的切换,比如将数据流切换到IO线程执行耗时操作,或者将结果切换回主线程更新UI。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/161961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++二分算法:得到子序列的最少操作次数

本文涉及的基础知识点 二分查找算法合集 题目 给你一个数组 target &#xff0c;包含若干 互不相同 的整数&#xff0c;以及另一个整数数组 arr &#xff0c;arr 可能 包含重复元素。 每一次操作中&#xff0c;你可以在 arr 的任意位置插入任一整数。比方说&#xff0c;如果…

【如何学习Python自动化测试】—— 多层窗口定位

6 、 多层窗口定位 多层窗口指的是在操作系统图形界面中&#xff0c;一个窗口被另一个窗口覆盖的情况。在多层窗口中&#xff0c;如何定位需要操作的窗口&#xff1f; 一种常见的方法是使用操作系统提供的AltTab快捷键&#xff0c;可以在打开的所有窗口中快速切换焦点。如果需要…

第十三章 控制值的转换 - 处理UTC时区指示符

文章目录 第十三章 控制值的转换 - 处理UTC时区指示符 第十三章 控制值的转换 - 处理UTC时区指示符 对于支持XML的类&#xff0c;可以指定在从XML文档导入时是否使用UTC时区指示符。同样&#xff0c;可以指定是否在导出时包含UTC时区指示符。 为此&#xff0c;指定XMLTIMEZON…

GEE生物量碳储量——利用sens和MK检验方法计算1987-2022年森林地上生物量AGB和碳储量的时空变化特征

简介: 本文是将之前已经处理好的森林生物量和碳储量数据保存到GEE Assets中,然后分别将单张影像导入到代码编辑器中,构建一个时间序列集合,并且这里需要用到的是我们给影像添加指定的时间属性,这样方便进行下一步的时序分析和空间预测。 首先,需要收集1987年至2022年期…

C语言实现Linux下TCP Server测试工具

Linux TCP Server测试工具代码 实现了接受数据并输出文本和十六制字符串 #include <stdio.h> #include<string.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <signal.h> #include <arpa/inet.h> #incl…

STM32内存介绍

ROM是一种只读存储器&#xff0c;经历了从NOR Flash到NAND Flash再到现在的eMMC的发展。为了便于使用和大批量生产&#xff0c;ROM进一步分为了4种类型&#xff1a;PROM、EPROM、EEPROM和Flash。PROM只能被编程一次&#xff0c;EPROM可擦写可编程且可达1000次&#xff0c;EEPRO…

leetcode/hot100

文章目录 一、哈希1.两数之和2.字母异位词分组3.最长连续序列 二、双指针4. 移动零5.盛最多水的容器6.三数之和7.接雨水 三、滑动窗口8.无重复字符的最长子串9.找到字符串中所有字母异位词 四、子串10.和为 K 的子数组 一、哈希 1.两数之和 1. 两数之和 class Solution { pu…

规则引擎Drools使用,0基础入门规则引擎Drools(二)高级语法

文章目录 系列文章索引五、规则属性1、enabled属性2、dialect属性3、salience属性4、no-loop属性5、activation-group属性6、agenda-group属性7、auto-focus属性8、timer属性9、date-effective属性10、date-expires属性 六、Drools高级语法1、global全局变量2、query查询3、fun…

20231122给RK3399的挖掘机开发板适配Android12

20231122给RK3399的挖掘机开发板适配Android12 2023/11/22 9:30 主要步骤&#xff1a; rootrootrootroot-X99-Turbo:~$ tar --use-compress-programpigz -xvpf rk356x_android12_220722.tgz rootrootrootroot-X99-Turbo:~$ cd rk_android12_220722/ rootrootrootroot-X99-Tur…

rk3568 适配以太网(mac 2 mac)

rk3568 适配以太网(mac 2 mac) MDI(Media Dependent Interface)是以太网中的一种接口标准,用于连接物理层(PHY)和数据链路层(MAC)之间的传输介质。 在以太网中,MDI通常通过RJ-45插座来实现,用于连接网线和网络设备。MDI接口提供了电气和机械特性,使得PHY和MAC能够正…

Python通过串口收发文件

单位内外网是隔离的,USB对拷线被禁用,安全优盘使用太费事,就想到了通过串口传输文件. import serial from xmodem import XMODEM import osdef Send_File(filepath, portCOM8, baudrate115200):bn os.path.basename(filepath)filesize os.stat(filepath).st_sizestrSendFile…

带记忆的超级GPT智能体,能做饭、煮咖啡、整理家务!

随着AI技术的快速迭代&#xff0c;Alexa、Siri、小度、天猫精灵等语音助手得到了广泛应用。但在自然语言理解和完成复杂任务方面仍然有限。 相比文本的标准格式&#xff0c;语音充满复杂性和多样性&#xff08;例如&#xff0c;地方话&#xff09;,传统方法很难适应不同用户的…

【每日OJ —— 20.有效的括号(栈)】

每日OJ —— 20.有效的括号&#xff08;栈&#xff09; 1.题目&#xff1a;20.有效的括号&#xff08;栈&#xff09;2.方法讲解2.1.解法2.1.1.算法讲解2.1.2.代码实现2.1.3.提交通过展示 1.题目&#xff1a;20.有效的括号&#xff08;栈&#xff09; 2.方法讲解 2.1.解法 利用…

2023 年 亚太赛 APMCM (B题)国际大学生数学建模挑战赛 |数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 问题一&#xff1a; 建立没有作物的玻璃温室内的温度和风速分…

C语言二十四弹--喝汽水问题

C语言解决喝汽水问题 题目&#xff1a;喝汽水&#xff0c;1瓶汽水1元&#xff0c;2个空瓶可以换一瓶汽水&#xff0c;给20元&#xff0c;可以喝多少汽水&#xff1f; 方法一、逐瓶购买法 思路&#xff1a;一瓶瓶的买 当空瓶有两个时&#xff0c;汽水数加1即可。 #include &…

MacOS 成为恶意软件活动的目标

Malwarebytes 警告称&#xff0c;一个针对 Mac 操作系统 (OS) 的数据窃取程序正在通过虚假的网络浏览器更新分发给毫无戒心的目标。 Atomic Stealer&#xff0c;也称为 AMOS&#xff0c;是 Mac OS 上流行的窃取程序。 Atomic Stealer (AMOS) 恶意软件最近被发现使用“ClearFa…

ImportError: cannot import name ‘contextfilter‘ from ‘jinja2‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

汇编-pop出栈指令

32位汇编 执行动作分为两步&#xff1a; 第一步&#xff1a;读出数据 第二步&#xff1a;改变栈地址 如果操作数是16位&#xff0c; 则ESP加2&#xff1b; 如果操作数是32位&#xff0c; 则ESP加4 espesp2 或 espesp4 格式&#xff1a;

九、sdl显示bmp图片

前言 SDL中内置加载BMP的API&#xff0c;使用起来会更加简单&#xff0c;便于初学者学习使用SDL 如果需要加载JPG、PNG等其他格式的图片&#xff0c;可以使用第三方库&#xff1a;SDL_image 测试环境&#xff1a; ffmpeg的4.3.2自行编译版本windows环境qt5.12sdl2.0.22&…

力扣第462题 最小操作次数使数组元素相等 II C++ 排序基础 附Java代码

题目 462. 最小操作次数使数组元素相等 II 中等 相关标签 数组 数学 排序 给你一个长度为 n 的整数数组 nums &#xff0c;返回使所有数组元素相等需要的最小操作数。 在一次操作中&#xff0c;你可以使数组中的一个元素加 1 或者减 1 。 示例 1&#xff1a; 输入&a…