首先看一段Map函数的使用代码:

        Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onNext(123);
}
}).map(new Func1<Integer, String>() { @Override
public String call(Integer integer) {
return integer.toString();
}
}).subscribe(new Subscriber<String>() {
public static final String TAG ="Test" ; @Override
public void onCompleted() {
} @Override
public void onError(Throwable e) {
} @Override
public void onNext(String s) {
Log.d(TAG, "onNext: "+s);
}
});

Observable<Integer>Observable1=Observable.create(new Observable.OnSubscribe<Integer>() {
    @Override

public void call(Subscriber<? super Integer> subscriber) { subscriber.onNext(123); }

});

create函数构建了一个新的Observable 在Observable的构造函数中将Observable.onSubscribe属性赋值为 Observable.OnSubscribe<Integer>;
Observable<String> Observable2= Observable1.map(new Func1<Integer, String>() {
     @Override
     public String call(Integer integer) {
     return null;
   }});
通过 map函数构建了一个新的Observable
map函数源码:
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
     return lift(new OperatorMap<T, R>(func));
}
在map源码中首先通过func(这里的func指的就是Func1<Integer, String>())参数构建一个OperatorMap类;
public OperatorMap(Func1<? super T, ? extends R> transformer) {
   this.transformer = transformer;
}
OperatorMap.transformer 也指向了Func1<Integer, String>();

lift函数里面创建了一个新的Observable,而上边的Observable<String> Observable2也就是lift函数创建的;
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
return new Observable<R>(new OnSubscribeLift<T, R>(onSubscribe, operator));
}
public final class OnSubscribeLift<T, R> implements OnSubscribe<R>

在构造函数中传了一个OnSubscribeLift对象,因此Observable2.onSubscribe 也就指向了OnSubscribeLift;

public OnSubscribeLift(OnSubscribe<T> parent, Operator<? extends R, ? super T> operator) {
this.parent = parent;
this.operator = operator;
}
在OnSubscribeLift的构造函数中parent 被指向为Observable1中的OnSubscribe(Observable.OnSubscribe<Integer>())
operator指向OperatorMap;
通过Map函数就创建了一个新的Observable,所有开头的例子的代码就变成了
Observable2 .subscribe(new Subscriber<String>() {
public static final String TAG ="125" ;

@Override
public void onCompleted() {

}

@Override
public void onError(Throwable e) {

}

@Override
public void onNext(String s) {
Log.d(TAG, "onNext: "+s);
}
});
然后在分析下subscribe函数:
public final Subscription subscribe(Subscriber<? super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
在Observable.subscribe(subscriber, this); 中的this 指向的是Observable2;

static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
.................
subscriber.onStart();
hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);
return hook.onSubscribeReturn(subscriber);
.................
}
从subscribe函数代码可以看出,最终调用的是onSubscribe的call函数;
此时的onSubscribe指向的是Observable2.onSubscribe 也就是早lift函数中创建的OnSubscribeLift;
在OnSubscribeLift.java 代码中:
public void call(Subscriber<? super R> o) {
.............
Subscriber<? super T> st = hook.onLift(operator).call(o);

st.onStart();
parent.call(st);
............
}
在call函数中参数 Subscriber<? super R> o指向的是subscribe函数中的Subscriber<String>();
call函数的内部首先创建了一个新的 Subscriber<? super T> st;
此时的operator指向的是OperatorMap类
新的Subcriber(MapSubscriber对象)放入订阅列表中,以便最后一起把订阅对象释放。同时返回新的Subcriber。
public Subscriber<? super T> call(final Subscriber<? super R> o) {
   MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
   o.add(parent);
   return parent;
}
static final class MapSubscriber<T, R> extends Subscriber<T> {
  public MapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends R> mapper) {
   this.actual = actual;
   this.mapper = mapper;
  }
}
在OperatorMap类的call方法中创建了一个新的MapSubscriber对象;
在创建的MapSubscriber对象的构造函数中对字段进行赋值
actual 指向 o 也就是subscribe函数中的Subscriber<String>();
mapper 指向OperatorMap.transformer (指向了map函数的中参数Func1<Integer, String>())

回到在OnSubscribeLift.call 代码中,当创建好新的Subscriber对象后,将执行
parent.call(st);
此时的parent 指向的是Observable1中的OnSubscribe,因此调用的call方法相当于是
public void call(Subscriber<? super Integer> subscriber) {
  subscriber.onNext(123);
}
此时的subscriber 就是新建的st(MapSubscriber) 跳转到onNext函数中;
static final class MapSubscriber<T, R> extends Subscriber<T> {
public void onNext(T t) {
  R result;

try {
     result = mapper.call(t);
   } catch (Throwable ex) {
   Exceptions.throwIfFatal(ex);
   unsubscribe();
   onError(OnErrorThrowable.addValueAsLastCause(ex, t));
   return;
  }

actual.onNext(result);
}
}
此时的参数t为123;执行mapper.call(t);
mapper此时执行的是
public String call(Integer integer) {
return integer.toString();
}
result 就变为了"123";
然后在执行actual.onNext("123");
actual此时就是:
public void onNext(String s) {
Log.d(TAG, "onNext: "+s);
}

到现在为止,整个流程代码就分析完成了

RxJava 中的Map函数原理分析的更多相关文章

  1. map函数原理

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #map函数 #map函数会对一个序列对象中的每一个元素应用被传入的函数,并返回一个包含了所有函数调用结果的一 ...

  2. perl编程中的map函数示例

    转自:http://www.jbxue.com/article/14854.html 发布:脚本学堂/Perl  编辑:JB01   2013-12-20 10:20:01  [大 中 小] 本文介绍 ...

  3. Python中的map()函数和reduce()函数的用法

    Python中的map()函数和reduce()函数的用法 这篇文章主要介绍了Python中的map()函数和reduce()函数的用法,代码基于Python2.x版本,需要的朋友可以参考下   Py ...

  4. python中的map()函数

    MapReduce的设计灵感来自于函数式编程,这里不打算提MapReduce,就拿python中的map()函数来学习一下. 文档中的介绍在这里: map(function, iterable, .. ...

  5. Python连载43-current中的map函数、xml文件

    一.current中的map函数 1.map(fn,*iterable,timeout=None) (1)跟map函数相类似(2)函数需要异步执行(3)timeout代表超时时间 (4)map和sub ...

  6. 关于boost中enable_shared_from_this类的原理分析

    首先要说明的一个问题是:如何安全地将this指针返回给调用者.一般来说,我们不能直接将this指针返回.想象这样的情况,该函数将this指针返回到外部某个变量保存,然后这个对象自身已经析构了,但外部变 ...

  7. 实现python中的map函数

    假设Python没有提供map()函数,自行编写my_map()函数实现与map()相同的功能.以下代码在Python 2.7.8中实现. 实现代码: def my_map(fun,num): i = ...

  8. Python 中的map函数,filter函数,reduce函数

      自学python,很多地方都需要恶补.       三个函数比较类似,都是应用于序列的内置函数.常见的序列包括list.tuple.str.   1.map函数 map函数会根据提供的函数对指定序 ...

  9. RxJava 中的map与flatMap

    1.map和flatMap都是接受一个函数作为参数(Func1) 2.map函数只有一个参数,参数一般是Func1,Func1的<I,O>I,O模版分别为输入和输出值的类型,实现Func1 ...

随机推荐

  1. 部署apollo-client到maven私服上时遇到的问题及排查过程

    场景回顾: 应用客户端如果需要接入到Apollo配置服务中心的话,需要引用apollo-client的依赖包使之与config-server保持连接,从而可以及时的收到更新之后的配置信息. 1.将ap ...

  2. JVM类加载机制(转)

    原文出自:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运 ...

  3. Spring-1-I 233 Matrix(HDU 5015)解题报告及测试数据

    233 Matrix Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Descript ...

  4. spark 作业提交

    kafka-topics.sh --describe --zookeeper xxxxx:2181 --topic testkafka-run-class.sh kafka.tools.GetOffs ...

  5. googleBigTable

    Bigtable是一个分布式的结构化数据存储系统,它被设计用来处理海量数据:通常是分布在数千台普通服务器上的PB级的数据.Google的很多项目使用Bigtable存储数据,包括Web索引.Googl ...

  6. Druid学习之路 (一)Druid初识

    作者:Syn良子 出处:https://www.cnblogs.com/cssdongl/p/9588079.html 转载请注明出处 最近在学习和使用Druid.觉得一些章节有必要按照自己的理解翻译 ...

  7. arm-linux工具

    arm-linux工具的功能如下: arm-linux-addr2line 把程序地址转换为文件名和行号.在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上 ...

  8. Android中C可执行程序编译问题

    make:进入目录'/opt/FriendlyARM/tiny4412/android/android-4.1.2'make: *** 没有规则可以创建“out/target/product/gene ...

  9. ubuntu18.04编译openwrt前的准备

    1.获取openwrt源码 git clone https://github.com/openwrt/openwrt.git 2.安装一些库及必备程序: sudo apt-get install li ...

  10. Servlet3.0异步请求

    在Servlet3.0之前,Servlet采用Thread-Per-Request的方式处理请求 即每次Http请求都有一个线程从头到尾负责处理 如果一个请求需要进行IO操作,比如访问数据库.调用第三 ...