在 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. (转)什么是JSON+如何处理JSON字符串

    仍然是crifan的好文: http://www.crifan.com/summary_what_is_json_and_how_to_process_json_string/ . . . .

  2. iOS 控制台打印unicode 转中文汉字 UTF8String

    今天查看代码数据结构,就在控台直接打印了,soGa,我看到了什么!!!! 于是乎想到了不对劲,不对呀,之前打印都是 UTF8String的呀,怎么会这样,百思不得其姐,看了一下封装的网络类,SoGa, ...

  3. javascript学习教程

    我来班门弄斧一下吧,把我JavaScript学习过程中常去的一些网站分享给大家: =========================增加================================ ...

  4. 【Foreign】采蘑菇 [点分治]

    采蘑菇 Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output Sample Input 5 1 2 3 2 3 1 2 1 ...

  5. [POJ1637]混合图的欧拉回路判定|网络流

    混合图的欧拉回路判定 上一篇正好分别讲了有向图和无向图的欧拉回路判定方法 如果遇上了混合图要怎么做呢? 首先我们思考有向图的判定方法:所有点的出度=入度 我们可以先为无向边任意定一个向,算出此时所有顶 ...

  6. CodeVS1747_NOI2002_荒岛野人_Savage_C++

    题目:http://codevs.cn/problem/1747/ 对于一个环,我们经常用取余来表示它走过若干圈后的位置 那么第 i 个野人第 x 年时所在的位置可表示为:(c[i]+p[i]*x)% ...

  7. Linux-进程间通信(二): FIFO

    1. FIFO: FIFO也被成为命名管道,因其通过路径关系绑定,可以用于任意进程间通信,而普通无名管道只能用于有共同祖先的进行直接通信; 命名管道也是半双工的,open管道的时候不要以读写方式打开, ...

  8. 第三篇:使用firewall-cmd

    本文来源:Working with firewalld         其它参考文档:redhat官方中文文档 1.查询类命令 2.设置类命令 3.运行时zone设置 4.永久性zone设置 5.直接 ...

  9. JAVA集合操作的利器:CollectionUtils

    使用 CollectionUtils 中四个方法之一执行集合操作.这四种分别是 union(),intersection();disjunction(); subtract(); 下列例子就是演示了如 ...

  10. 记一次Laravel定时任务导致日志没有写入权限的坑

    问题:用laravel开发定时任务时,发生了日志没有写入权限导致项目打不开的问题 原因:linux的添加定时任务时默认是当前登录用户,我定时任务会生成日志 crontab: kernel: 生成日志的 ...