在 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. java.sql.Date和java.util.Date的不同和相互转换方式

    一:前言 这是我在新的公司写的第一份博客吧,来了又一个星期了吧,但是在来的那几天我真的很迷茫的感觉这里是很不适合我的样子,而且我又是来实习的,我很不愿意啊,自己做的又是java web,最原始的ser ...

  2. 修改nginx对http请求数据大小限制

    1. 问题发现 在公司搭建了一个基于mindoc的wiki知识库,用nginx做的反向代理服务器,同事在使用过程中上传某个文件一直失败,于是看着看下mindoc自己的日志文件,发现都是类似于fastd ...

  3. HDU2066一个人的旅行---(多起点多终点最短路径)

    http://acm.hdu.edu.cn/showproblem.php?pid=2066 一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memo ...

  4. 【BZOJ3680】吊打xxx [模拟退火]

    吊打XXX Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description gty又虐了一场比赛,被虐的蒟蒻 ...

  5. 【Foreign】红与蓝 [暴力]

    红与蓝 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 2 2 0 1 -1 -1 2 0 ...

  6. loj6029 「雅礼集训 2017 Day1」市场

    传送门:https://loj.ac/problem/6029 [题解] 考虑如果有一些近似连续的段 比如 2 2 2 3 3 3,考虑在除3意义下,变成0 0 0 1 1 1,相当于整体-2 又:区 ...

  7. UNREFERENCED_PARAMETER()的作用

    告诉编译器,已经使用了该变量,不必警告. 在VC编译器下,当你声明了一个变量,而没有使用时,编译器就会报警告: “warning C4100: ''XXXX'' : unreferenced form ...

  8. Kuangbin 带你飞 最小生成树题解

    整套题都没什么难度. POJ 1251 Jungle Roads #include <map> #include <set> #include <list> #in ...

  9. HTTP===返回结果的HTTP状态码

    HTTP 状态码负责表示客户端 HTTP 请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. 1.状态码告知从服务器端返回的请求结果 状态码的职责是当客户端向服务器端发送请求时,描述返 ...

  10. 定义序列化器时的read_only和write_only选项

    # 转载请留言联系 read_only read_only表示只能读,不能进行修改.例如定义序列化器时,id字段通常指定read_only=True.在序列化时,即对象转为字典.JSON字符串时,字典 ...