RxJava2源码分析——Map操作符

2023-05-16

本文章用的RxJavaRxAndroid版本如下:

implementation 'io.reactivex.rxjava2:rxjava:2.2.6'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
复制代码

我们先写段示例代码,为了方便理解,在调用map方法的时候,我就不用上Lambda链式调用了,代码如下:

Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
    emitter.onNext(100);
    emitter.onComplete();
})
        .map(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) {
                return integer.toString();
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                // no implementation
            }

            @Override
            public void onNext(String s) {
                Log.i("TanJiaJun", "变换后的:" + s);
            }

            @Override
            public void onError(Throwable e) {
                // no implementation
            }

            @Override
            public void onComplete() {
                // no implementation
            }
        });
复制代码

这段代码是将Integer类型的数据100变换为String类型的100后发射出去。

源码分析

我们看下map方法的源码,代码如下:

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
    ObjectHelper.requireNonNull(mapper, "mapper is null");
    return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
复制代码

参数是泛型接口Function<? super T, ? extends R>,有两个类型参数,第一个参数是一个下边界通配符(Lower Bounded Wildcard),对应逆变,可以存放TT的父类型,第二个参数是一个上边界通配符(Upper Bounded Wildcard),对应协变,可以存放RR的子类型。

根据前几篇文章的经验可知,我们只要看ObservableMap这个类就行了,代码如下:

public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    final Function<? super T, ? extends U> function;

    public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
        // source是上游Observable
        super(source);
        this.function = function;
    }

    @Override
    public void subscribeActual(Observer<? super U> t) {
        // 调用了上游Observable的subscribe方法,传入new出来的MapObserver对象,第一个参数是下游Observer,第二个参数是Function泛型接口
        source.subscribe(new MapObserver<T, U>(t, function));
    }

    static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
        final Function<? super T, ? extends U> mapper;

        MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
            // actual是传进来的下游Observer,mapper是传进来的Function泛型接口
            super(actual);
            this.mapper = mapper;
        }

        @Override
        public void onNext(T t) {
            if (done) {
                return;
            }

            if (sourceMode != NONE) {
                downstream.onNext(null);
                return;
            }

            // U是要转变的对象
            U v;

            try {
                // 调用了Function泛型接口的apply方法,这是我们要重写的方法,参入的参数是转变前的对象
                v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
            } catch (Throwable ex) {
                fail(ex);
                return;
            }
            // 调用onNext方法,把转变后的对象发射出去
            downstream.onNext(v);
        }

        @Override
        public int requestFusion(int mode) {
            return transitiveBoundaryFusion(mode);
        }

        @Nullable
        @Override
        public U poll() throws Exception {
            T t = qd.poll();
            return t != null ? ObjectHelper.<U>requireNonNull(mapper.apply(t), "The mapper function returned a null value.") : null;
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RxJava2源码分析——Map操作符 的相关文章

  • 怎样为std::map的自定义key提供比较操作(一)

    stl的关联容器 map set 的key一般要求提供 lt 比较操作 假设我们有一个结构SomeKey struct SomeKey int a b 要想以SomeKey作为std map的key 需要为这个结构提供operator lt
  • 【数据结构】Map 映射

    数据结构源码 接口 public interface Map
  • Golang 中实现注解功能的思路分析

    文章目录 注解的作用 一些实现注解的开源 Golang 工程 Golang 中实现注解的基本思路 第一步 源码词法分析 第二步 代码生成 第三步 自动执行 番外 Golang 中一种代替注解的方案 注解的作用 提到注解 需要短暂的说明其前世
  • 2020年团体程序设计天梯赛-总决赛 L2-2 口罩发放

    L2 2 口罩发放 25分 输入格式 输出格式 输入样例 输出样例 样例解释 题解 L2 2 口罩发放 25分 为了抗击来势汹汹的 COVID19 新型冠状病毒 全国各地均启动了各项措施控制疫情发展 其中一个重要的环节是口罩的发放 某市出于
  • [python] 下载天地图切片地图

    下载xyz地图 资源 下列为常用xyz路由地址 为了避免图片中出现文字标注 道路名称 建筑物名称等 本文选择天地图tian vec 作为获取资源对象 var mapUrl 高德地图 lang可以通过zh cn设置中文 en设置英文 size
  • IDEA国际化资源Key无法全局重命名的解决方案

    一 前言 最近在开发中使用到了HibernateValidator进行入参校验以及错误消息的国际化支持 大家应该都知道在使用HibernateValidator进行校验的时候 我们只需在需要在校验的变量上添加相应的注解 同时在message
  • java Map集合

    目录 一 介绍 二 HashMap 三 TreeMap 四 LinkedHashMap 一 介绍 Java中的Map是一种键值对的集合数据类型 用于存储无序的 不重复的键值对 它提供了快速的查找和访问功能 可以根据键来获取值 常见的Map实
  • RxJava 2 / Retrofit 2 - NetworkOnMainThreadException

    我需要执行请求 如果我的令牌已过期 我需要刷新它并重试该请求 这就是我尝试执行此操作的方式 目前我可以刷新令牌 但它会向我抛出 NetworkOnMainThreadException 它完成了请求 更新了令牌并到达了日志 但是这个异常让我
  • Lateinit 属性数据尚未初始化

    使用 Retrofit2 和 rxjava2 未在 Recyclerview 中设置 Gson Convertable 数据 然后通过其订阅给出错误 UninitializedPropertyAccessException lateinit
  • 使用函数引用在 Kotlin 中重写 Java 代码发生 SAM 类型冲突

    我有一个使用方法引用的示例 Java 代码 我想将其重写为 Kotlin Java版本使用方法参考 解决方案简短明了 但另一方面 我无法在 Kotlin 中使用方法引用 我设法编写的唯一版本是下面的版本 这好像是Function3 s St
  • 两个有序可观察量的完全外连接

    假设我们有两个可观察量Observable
  • RxJava 缓冲区直到更改

    我有一个可观察的对象 它会发出大量数据 例如 1 1 1 2 2 2 3 3 1 1 5 5 在RxJava中我们可以使用直到改变 http reactivex io documentation operators distinct htm
  • 使用 RxJava 的状态机?

    我正在尝试全力以赴地使用 RxJava 并解决我遇到的这个问题 但它似乎非常不适合它 因为 RxJava 似乎不想处理任何类型的状态 而只是传递事件并改变它们来处理它们 我尝试用 RxJava 模拟的基本状态机行为是这样的 在应用程序启动事
  • RxJava2 发布

    有什么区别 ObservableTransformer Observable merge it ofType x compose transformerherex it ofType y compose transformerherey a
  • 使用 Retrofit2 以表单 urlencoded 请求发送对象列表

    这是我的邮递员请求 我将使用 Retrofit2 Gson 和 RxJava2 发送 POST 请求 这是我的要求 FormUrlEncoded POST Student I m sure the address and name are
  • 每分钟重复一次可观察的最好方法 rxjava

    我有以下方法 public class ParentalControlInteractor public Single
  • RxJava2 + Room:clearAllTables() 调用后数据未插入数据库

    成功后在我的Android应用程序中login我将会话信息保存在 Room 中 然后从 BE 检索用户信息并保存它 一切正常 我可以看到数据库表中保存的信息 When 用户注销从应用程序中 所有表都通过 appDatabase clearA
  • 使用 RxJava 处理长时间运行的任务

    我正在尝试迁移AsyncTask向服务器发送消息 使用 RxJava 粗略地说 该任务执行以下操作 1 创建一条将要发送的消息 保存到数据库 2 向用户显示消息 状态 正在发送 3 向服务器发送消息 代码片段如下 4 将消息标记为已发送或失
  • 在 RxJava 2 中展平列表

    我已经使用 RxJava 1 一段时间了 但我想看看 RxJava 2 在 RxJava 1 中 我可以发出列表中的每个项目 如下所示 List
  • 调试 Java InterruptedException,即查找原因

    在调试Android应用程序时 有时中断异常发生并使应用程序崩溃 我已经能够在默认异常处理程序上设置断点 但调用堆栈不提供信息 at java util concurrent locks AbstractQueuedSynchronizer

随机推荐

  • Activity启动流程(一)

    Launcher进程请求AMSAMS发送创建应用进程请求Zygote进程接受请求并孵化应用进程应用进程启动ActivityThread 一 Launcher进程请求AMS 上面我们提到根Activity的启动流程其实就是桌面上点击一个应用图
  • Activity启动流程(二)

    应用进程绑定到AMSAMS发送启动Activity的请求ActivityThread的Handler处理启动Activity的请求 一 应用进程绑定到AMS 1 时序图 2 详细过程 在前面一篇我们知道当Zygote进程孵化出应用进程后会执
  • AudioRecord

    数字音频 数字音频通常分为三步 xff1a 采样 量化 编码 采样 xff1a 就是将获取的信号给数字化 xff0c 其中有个概念就是采样频率 xff0c 而人耳能听到的频率范围只有20Hz 20kHz xff0c 所以一般设置的都是44
  • GCC编译C/C++程序(一步完成)

    使用 GCC 编译器编译 C 或者 C 43 43 程序 xff0c 也必须要经历这 4 个过程 但考虑在实际使用中 xff0c 用户可能并不关心程序的执行结果 xff0c 只想快速得到最终的可执行程序 xff0c 因此 gcc 和 g 4
  • GCC -E选项:对源程序做预处理操作

    存储在 demo c 文件中 include lt stdio h gt int main puts 34 hello world 34 return 0 通过为 gcc 指令添加 E 选项 xff0c 即可控制 GCC 编译器仅对源代码做
  • GCC -S选项:编译非汇编文件

    root 64 bogon demo cat demo c include lt stdio h gt int main puts 34 Hello World 34 return 0 root 64 bogon demo gcc E de
  • GCC -c选项:生成目标文件

    root 64 bogon demo ls demo c root 64 bogon demo cat demo c include lt stdio h gt int main puts 34 Hello World 34 return
  • GCC -l选项:手动添加链接库

    标准库的大部分函数通常放在文件 libc a 中 xff08 文件名后缀 a代表 achieve xff0c 译为 获取 xff09 xff0c 或者放在用于共享的动态链接文件 libc so 中 xff08 文件名后缀 so代表 shar
  • GCC 编译使用动态链接库和静态链接库

    1 库的分类 根据链接时期的不同 xff0c 库又有静态库和动态库之分 静态库是在链接阶段被链接的 xff08 好像是废话 xff0c 但事实就是这样 xff09 xff0c 所以生成的可执行文件就不受库的影响了 xff0c 即使库被删除了
  • python爬虫——爬取数据导入excel表

    1 导入第三方库 requests库 re html xlwt span class token keyword from span bs4 span class token keyword import span BeautifulSou
  • Makefile call函数

    引用变量的格式为 变量名 xff0c 函数调用的格式如下 xff1a lt function gt lt arguments gt 或者是 lt function gt lt arguments gt 其中 xff0c function 是
  • Glide生命周期绑定

    Glide class和RequestManagerRetriever class xff0c 主要用来获得RequestManager with返回一个RequestManager public static RequestManager
  • Glide缓存机制

    Glide中采用计数的方式统计资源的引用 xff0c 在每个EngineResource内部都设置一个引用计数acquired xff0c 在加载资源时引用 43 43 xff0c 释放资源时引用 xff1a class EngineRes
  • UML类图

    类图 xff08 Class Diagrams xff09 xff1a 用户根据用例图抽象成类 xff0c 描述类的内部结构和类与类之间的关系 xff0c 是一种静态结构图 在UML类图中 xff0c 常见的有以下几种关系 泛化 xff08
  • android源码github

    https github com aosp mirror platform frameworks base
  • jar 包转 java

    jd gui 内 File gt Save All Sources 直接保存到本地
  • DataBinding源码解析

    DataBinding是Google发布的支持库 xff0c 它可以实现UI组件及数据源的双向绑定 使用DataBinding可以轻松实现MVVM模式 xff0c 当数据发生变化时会体现在View界面上 xff0c 反过来界面内容变化也会同
  • LiveData源码分析

    首先还是以一个示例开始 xff1a MutableLiveData lt String gt liveString 61 new MutableLiveData lt gt liveString observe mOwner new Obs
  • ViewModel源码分析

    首先 xff0c 还是先看一个例子 xff1a public class MyViewModel extends ViewModel private MutableLiveData lt List lt User gt gt users p
  • RxJava2源码分析——Map操作符

    本文章用的RxJava和RxAndroid版本如下 xff1a implementation 39 io reactivex rxjava2 rxjava 2 2 6 39 implementation 39 io reactivex rx