尊重他人的劳动成果,转载请标明出处:http://blog.csdn.net/gengqiquan/article/details/52757393, 本文出自:【gengqiquan的博客】
关于Map变换操作符,ReactiveX文档上的定义是这样的
对Observable发射的每一项数据应用一个函数,执行变换操作
Map操作符对原始Observable发射的每一项数据应用一个你选择的函数,然后返回一个发射这些结果的Observable。
RxJava将这个操作符实现为map函数。这个操作符默认不在任何特定的调度器上执行。
第一次看文档的时候看到一堆这种图,什么玩意儿!然后看多了就懂了。
map变换操作符的作用是把每一个(T类型的)Observable通过一些列代码变换成另外一种(R类型的)Observable
也就是图上的把圆圈变成三角。
Observable就是流,把他当做一种结构,这种结构具有类型, 这种类型可以应用rx操作。然后实际进行RX操作的时候操作的其实是对应的类型的对象。
在Java里的实现为
可以看到方法的定义,传入的是一种类型T(super前面的?)Observable,返回的是 另一种类型R以及R的子类(extends前面的?)Observable
比如现在我们有一个 String类型的Observable,现在要把它通过rx操作变换成integer类型的Observable
代码可以这样写
rx.Observable.just("s")
.map(new Func1<String, Integer>() {
@Override
public Integer call(String s) {
return Integer.valueOf(s);
}
})
使用lambda精简后可以这样写
rx.Observable.just("s")
.map(s-> {return Integer.valueOf(s);})
甚至可以这样写
rx.Observable.just("s")
.map(s-> Integer.valueOf(s))
String就是我们上面说的T类型,Integer就是我们上面说的R类型。你可能会觉得把String类型转换成integer而已,这样写是不是太复杂了,别担心,这只是个例子,为了尽量简单的告诉大家map的作用
想象一下,你从服务端获取了一个json数据,但界面最终想要的可能只是里面的某个对象。但你又不得不兼容错误处理,状态码判断,传统的写法可能是写在一个函数里,然后进行各种解析判断比如下面这样
.Success(json -> {
BaseModel model = new BaseModel(json );
if (model.status) {
mMakeParams = params;
MakePriceOrderInfo info = (MakePriceOrderInfo) JsonUtil.fromJson(model.data, MakePriceOrderInfo.class);
startActivity(new Intent(mContext, PayActivity.class)
.putExtra("type", "2")
.putExtra("order_id", info.getOrder_id()));
} else {
ToastUtil.showShort(mContext, model.msg);
}
})
.Error(v -> ToastUtil.showShort(mContext, v[1]))
BaseModel 是服务器返回的固定格式
public class BaseModel {
public String data;
public String msg;
public boolean status;
}
但你不其实并不想最终的订阅对象(界面赋值函数)去处理太多的条件判断。或者对象类型变换。
因为那样耦合很重,同时代码也并不利于阅读。此时你就可以利于map操作符去对数据源进行变换,变换成订阅对象需要的类型再传递给订阅对象
比如这样
.map(s -> new BaseModel(s))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.filter(model -> model.trueStatus(context))//筛选操作符,只返回为真的情况下的数据
.map(model -> model.data);
.subscribe(data -> {
String report_id = (String) JsonUtil.parreskey(data, "report_id");
if (Util.isEmpty(report_id)) {
showBuyDialog( data);
} else {
startActivity(new Intent(this, MakePriceActivity.class)
.putExtra("isleft", true)
.putExtra("report_id", report_id));
}
}, e -> ToastUtil.showShort(mContext, e.getMessage()));
trueStatus方法判断是否返回正确的数据,否则toast提示
public boolean trueStatus(Context context) {
if (status) {
return true;
} else {
ToastUtil.showShort(context, msg);
return false;
}
}
如此一来你的订阅对象subscribe只需要处理他自己所需要的data 数据了。而不用管在把这个数据给他之前你做了多少事情,因为他不需要在意这些事。
我建了一个QQ群(群号:121606151),用于大家讨论交流Android技术问题,有兴趣的可以加下,大家一起进步。