RxJava实战:变换操作符map的使用姿势及技巧

尊重他人的劳动成果,转载请标明出处:http://blog.csdn.net/gengqiquan/article/details/52757393, 本文出自:【gengqiquan的博客】

关于Map变换操作符,ReactiveX文档上的定义是这样的

对Observable发射的每一项数据应用一个函数,执行变换操作
map

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技术问题,有兴趣的可以加下,大家一起进步。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值