在 RxJava 1.x 理解-1 中,我们说到了RxJava的简单用法,但是这还远远不够,因为

输入的数据 ---> 被监听者(订阅源)对这些数据进行操作,或者执行响应的处理 --> 产生新的数据,或者事件发送给监听者 --> 监听者执行自己的方法。

其中,RxJava还可以对输入的数据进行变换,产生新数据(可以是复杂的数据),而不是简单的事件触发。

先将数据的提供,进阶一下:

rxJava just 使用

    /**
* rxJava just 使用
* just --> 还是使用的create方法
*/
private void rxJavaJust() {
Log.d(TAG, "----------- just ---------"); Observable
.just("just 1", "just 2", "just 3")
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d(TAG, "Item: " + s);
}
});
}

just会不断的将可变参数数据 just 1 ;just 2 ;just 3 .... 发送出去

rxJava from 使用

    /**
* rxJava from 使用
* from --> 还是使用的create方法
*/
private void rxJavaFrom() {
Log.d(TAG, "----------- from ---------"); String[] names = {"1", "2", "3"};
Observable.from(names)
.subscribe(new Subscriber<String>() {
@Override
public void onNext(String s) {
Log.d(TAG, "Item: " + s);
} @Override
public void onCompleted() {
Log.d(TAG, "Completed!");
} @Override
public void onError(Throwable e) {
Log.d(TAG, "Error!");
}
}); Log.d(TAG, "----------- from2 ---------"); // 简单来说就是数据提供了,而且是一个个的提供了,至于要如何执行,那就按观察者自己的事情了。
Observable.from(names)
.subscribe(new Action1<String>() { @Override
public void call(String s) {
Log.d(TAG, "Item: " + s);
} });
}

from会不断的将数组或者集合中的数据一个个发送出去

数据变换

rxjava map 变换

    /**
* rxjava map 变换
* 将类型转化成另一个类型
*/
private void rxJavaMap() {
Log.d(TAG, "----------- Map ---------"); Observable.just("1") // 输入类型 String
.map(new Func1<String, Integer>() {
@Override
public Integer call(String s) {
return Integer.parseInt(s);
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d(TAG, "Item: " + integer + " 执行调用 获取线程id:" + Thread.currentThread().getId());
}
});
}
        Observable.just("999", "11") // 输入类型 String
.map(new Func1<String, List<Integer>>() {
@Override
public List<Integer> call(String s) {
List<Integer> ints = new ArrayList<>();
ints.add(Integer.parseInt(s));
ints.add(Integer.parseInt(s));
ints.add(Integer.parseInt(s));
return ints;
}
}).subscribe(new Action1<List<Integer>>() {
@Override
public void call(List<Integer> integers) {
int i = 0;
// 这里进行遍历
for (Integer integer : integers) {
Log.e(TAG, "Item " + i + " :" + +integer);
i += 1;
}
}
}); }

可以看到,将String格式的数据转换成了Integer格式的数据,或者是String格式的数据转换成List<Integer>格式的数据。map是一对一的变换。

rxjava flatMap 变换

    /**
* rxjava flatMap 变换
* 事件再次分发:
*
* 从上面的代码可以看出, flatMap() 和 map() 有一个相同点:它也是把传入的参数转化之后返回另一个对象。
* 但需要注意,和 map() 不同的是, flatMap() 中返回的是个 Observable 对象,但这个 Observable 对象并不是被直接发送到了 Subscriber 的回调方法中。
* flatMap() 的原理是这样的:
* 1. 使用传入的事件对象创建一个 Observable 对象;
* 2. 并不发送这个 Observable, 而是将它激活,于是它开始发送事件;
* 3. 每一个创建出来的 Observable 发送的事件,都被汇入同一个 Observable ,而这个 Observable 负责将这些事件统一交给 Subscriber 的回调方法。
* 这三个步骤,把事件拆成了两级,通过一组新创建的 Observable 将初始的对象『铺平』之后通过统一路径分发了下去。而这个『铺平』就是 flatMap() 所谓的 flat。
*/
private void rxJavaFlatMap() {
Log.d(TAG, "----------- rxJavaFlatMap ---------"); List<Student> students = new ArrayList<>();
List<Source> sources = new ArrayList<>();
sources.add(new Source(1, "化学", 80));
sources.add(new Source(2, "物理", 79));
sources.add(new Source(3, "生物", 78));
students.add(new Student("小明1", 1, sources));
students.add(new Student("小明2", 1, sources));
Observable.from(students)
.flatMap(new Func1<Student, Observable<Source>>() {
@Override
public Observable<Source> call(Student student) {
Log.d(TAG, "Item: " + student.name);
return Observable.from(student.mSources);
}
})
.subscribe(new Action1<Source>() {
@Override
public void call(Source source) {
Log.d(TAG, "Item: " + source + " 执行调用 获取线程id:" + Thread.currentThread().getId());
}
});
}
 // ------------------------ 测试使用的类 -----------------------------

    class Student {
String name;//学生名字
int id;
List<Source> mSources;//每个学生的所有课程 public Student(String name, int id, List<Source> sources) {
this.name = name;
this.id = id;
mSources = sources;
} @Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
", mSources=" + mSources +
'}';
}
} class Source {
int sourceId;//id
String name;//课程名
int score;//成绩 public Source(int sourceId, String name, int score) {
this.sourceId = sourceId;
this.name = name;
this.score = score;
} @Override
public String toString() {
return "Source{" +
"sourceId=" + sourceId +
", name='" + name + '\'' +
", score=" + score +
'}';
}
}

输出结果:

02-09 15:45:50.580 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: 小明1
02-09 15:45:50.581 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=1, name='化学', score=80} 执行调用 获取线程id:2
02-09 15:45:50.581 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=2, name='物理', score=79} 执行调用 获取线程id:2
02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=3, name='生物', score=78} 执行调用 获取线程id:2
02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: 小明2
02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=1, name='化学', score=80} 执行调用 获取线程id:2
02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=2, name='物理', score=79} 执行调用 获取线程id:2
02-09 15:45:50.583 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=3, name='生物', score=78} 执行调用 获取线程id:2

其实上述代码,也可以用map实现:

        Observable.from(students).map(new Func1<Student, List<Source>>() {
@Override
public List<Source> call(Student student) {
Log.d(TAG, "Item: " + student.name);
return student.mSources;
}
}).subscribe(new Action1<List<Source>>() {
@Override
public void call(List<Source> sources) {
// 主要的差距是这里,我们自己进行了一次循环遍历。而flatMap则不用,直接获取到的就是Source对象,而不是List<Source>对象
for (Source source:sources){
Log.d(TAG, "Item: " + source + " 执行调用 获取线程id:" + Thread.currentThread().getId());
}
}
});
从上面的代码可以看出, 
flatMap() 和 map() 有一个相同点:它也是把传入的参数转化之后返回另一个对象。
但需要注意,和 map() 不同的是, flatMap() 中返回的是个 Observable 对象,但这个 Observable 对象并不是被直接发送到了 Subscriber 的回调方法中。
flatMap() 的原理是这样的:
1. 使用传入的事件对象创建一个 Observable 对象;
2. 并不发送这个 Observable, 而是将它激活,于是它开始发送事件;
3. 每一个创建出来的 Observable 发送的事件,都被汇入同一个 Observable ,而这个 Observable 负责将这些事件统一交给 Subscriber 的回调方法。
这三个步骤,把事件拆成了两级,通过一组新创建的 Observable 将初始的对象『铺平』之后通过统一路径分发了下去。而这个『铺平』就是 flatMap() 所谓的 flat。 总结:RxJava的作用就是
对于数据:对输入的数据进行变换,转换成想要的数据,并且可以指定执行的线程,得到最终的结果。
对于事件:触发事件,观察者感知,观察者执行操作,并且可以指定执行的线程。

参考资料:

一起来造一个RxJava,揭秘RxJava的实现原理

给 Android 开发者的 RxJava 详解

RxJava 1.x 理解-3的更多相关文章

  1. RxJava 2.x 理解-3

    背压:Flowable / Subscriber 在RxJava 1.x 理解 中,没有讲到背压这个概念,是因为学习太落后了,RxJava都出2了,所以直接在2上学. 背压是下游控制上游流速的一种手段 ...

  2. RxJava 2.x 理解-1

    在RxJava 1.x 系列中,讲解了RxJava的大致用法,因为现在都用RxJava 2了,所以Rxjava 1就不细讲,主要来学习RxJava 2. 基本使用: /** * rajava2 的基本 ...

  3. RxJava 1.x 理解-2

    给RxJava 加入线程控制 -- Scheduler 在 RxJava 1.x 理解-1 中,我们说到了RxJava的简单用法,但是这还远远不够,因为这简单用法是在同一个线程中使用的.比如我们需要在 ...

  4. RxJava 2.x 理解-2

    操作符总结: http://reactivex.io/documentation/operators.html https://github.com/ReactiveX/RxJava/wiki Ope ...

  5. RxJava 1.x 理解-1

    先看下别人实现的最基本的RxJava的实现方式: 在RxJava里面,有两个必不可少的角色:Subscriber(观察者) 和 Observable(订阅源). Subscriber(观察者) Sub ...

  6. RxJava+RxAndroid+MVP入坑实践(基础篇)

    转载请注明出处:http://www.blog.csdn.net/zhyxuexijava/article/details/51597230.com 前段时间看了MVP架构和RxJava,最近也在重构 ...

  7. 如何深入理解Java泛型

    一.泛型的作用与定义 1.1泛型的作用 使用泛型能写出更加灵活通用的代码泛型的设计主要参照了C++的模板,旨在能让人写出更加通用化,更加灵活的代码.模板/泛型代码,就好像做雕塑时的模板,有了模板,需要 ...

  8. 必读的 Android 文章

    必读的 Android 文章 掘金官方 关注 2017.06.07 13:58* 字数 25218 阅读 8782评论 2喜欢 218 写给 Android 开发者的混淆使用手册 - Android ...

  9. Android 使用Retrofit2.0+OkHttp3.0实现缓存处理+Cookie持久化第三方库

    1.Retrofit+OkHttp的缓存机制 1.1.第一点 在响应请求之后在 data/data/<包名>/cache 下建立一个response 文件夹,保存缓存数据. 1.2.第二点 ...

随机推荐

  1. L3-003. 社交集群(并查集)

    L3-003. 社交集群 时间限制 1000 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 在社交网络平台注册时,用户通常会输入自己的兴趣爱好, ...

  2. 【CF103D】Time to Raid Cowavans(分块)

    题意: 思路:院赛防AK题,然而还没来得及做就被数据出锅的题坑了…… #include<cstdio> #include<cstring> #include<string ...

  3. 【BZOJ】1571: [Usaco2009 Open]滑雪课Ski

    [算法]动态规划 [题解]yy出了O(1w log 1w)的算法. 将雪坡排序预处理出g[i]表示能力值为i的最短时长雪坡. 这样就可以定义work(t,c)表示时长t能力c的最多滑雪数量,work( ...

  4. 【洛谷 P1251】 餐巾计划问题 (费用流)

    题目链接 我做的网络流24题里的第一题.. 想是不可能想到的,只能看题解. 首先,我们拆点,将一天拆成晚上和早上,每天晚上会受到脏餐巾(来源:当天早上用完的餐巾,在这道题中可理解为从原点获得),每天早 ...

  5. [bzoj1009][HNOI2008]GT考试——KMP+矩阵乘法

    Brief Description 给定一个长度为m的禁止字符串,求出长度为n的字符串的个数,满足: 这个字符串的任何一个字串都不等于给定字符串. 本题是POJ3691的弱化版本. Algorithm ...

  6. IE 6 position不支持fixed属性的解决方案

    抛出另一个问题:IE7已经支持position:fixed了,而IE6却不支持,解决这个问题的办法如下: 现在有一个元素的id是element,它需要实现fixed效果,我们既想要它在正常的浏览器下使 ...

  7. Java相关框架

    框架 类型 设计(个人理解) HK2 自动注入框架 Jersey RESTful Jetty HTTP服务 Retrofit HTTP客户端 ActiveMQ 消息组件 主题.队列 Redis K-V ...

  8. Tomcat下载安装及常见问题解决办法

    一.Tomcat的下载: 下载地址:http://tomcat.apache.org/ 下载Tomcat6.0(在左侧的Download下,考虑到稳定性现在企业大部分还在用Tomcat6.0) (1) ...

  9. Python实现图片转字符画

    from PIL import Image def get_char(r, g, b, alpha=256): ascii_char = '''$@B%8&WM#*oahkbdpqwmZO0Q ...

  10. redis使用中的常见错误

    1.2016年12月17日  启动redis报错,错误信息如下: 解决办法:redis没有正常关闭(redis安装在虚拟机上,直接杀死了虚拟机进程) 导致redis.pid文件一直被锁定,重启redi ...