初涉RxAndroid .map() . filter() flatMap()

转载请注明出处:王亟亟的大牛之路

这周末又败家买了鱼缸和一套设备,本来预备端午出去玩玩的目测只能在家吃土,周五把之前的X项目从X的实现迁移到了RxJava(RxAndroid),这一篇也就写一下相关的知识

强行安利(日更):https://github.com/ddwhan0123/Useful-Open-Source-Android

How to use?

dependencies{
    compile ‘io.reactivex:rxjava:1.1.5‘
    compile ‘io.reactivex:rxandroid:1.2.0‘
    }

总共写了两个小例子,先看第一个

看下运行效果:

看下日志:

这个干了什么呢?我们有一个按钮点击之后 随机切换 image,当然图片就都是 异步下载的。

看下代码(先解释大致逻辑和第一部分,方法名命名请无视,哈哈哈)

public class TwoActivity extends AppCompatActivity implements View.OnClickListener {
    private Button testMap;
    private ImageView tiffanyImg;
    private RandomTools randomTools;
    private ArrayList<SampleModel> data;
    private TextView tiffanyText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_two);

        StatusBarCompat.compat(this, getResources().getColor(R.color.status_bar_color));
        StatusBarCompat.compat(this);

        findId();
        init();
        setListener();
        LogUtils.d("--->Main Thread  id " + Thread.currentThread().getId());
    }

    private void findId() {
        testMap = (Button) findViewById(R.id.testMap);
        tiffanyImg = (ImageView) findViewById(R.id.tiffanyImg);
        tiffanyText = (TextView) findViewById(R.id.tiffanyText);
    }

    private void init() {
        randomTools = RandomTools.getInstance();
        //填充数据
        makeSampleModelData();

    }

    private void setListener() {
        testMap.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.testMap:
                setPhotoForOne(data);
                // setPhotoForTwo(data);
                break;
        }

    }

    private void setPhotoForOne(ArrayList<SampleModel> data) {
        Observable.just(data)
                .subscribeOn(Schedulers.newThread())
                .map(new Func1<ArrayList<SampleModel>, SampleModel>() {
                    @Override
                    public SampleModel call(ArrayList<SampleModel> list) {
                        LogUtils.d("第一个call线程id " + Thread.currentThread().getId());
                        //模拟返回集合的某个元素
                        int randInt = randomTools.getRandom(4);
                        return list.get(randInt);
                    }
                }).map(new Func1<SampleModel, String>() {
            @Override
            public String call(SampleModel sampleModel) {
                LogUtils.d("第二个call线程id " + Thread.currentThread().getId());
                return sampleModel.getContent();
            }
        })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String url) {
                        LogUtils.d("第三个call线程id " + Thread.currentThread().getId());
                        LogUtils.d("--->开始加载 " + url);
                        Glide.with(TwoActivity.this).load(url).into(tiffanyImg);
                    }
                });

    }

    private void setPhotoForTwo(ArrayList<SampleModel> data) {
        Observable.just(data).subscribeOn(Schedulers.newThread())
                .flatMap(new Func1<ArrayList<SampleModel>, Observable<SampleModel>>() {
                    @Override
                    public Observable<SampleModel> call(ArrayList<SampleModel> sampleModels) {
                        return Observable.from(sampleModels);
                    }
                }).filter(new Func1<SampleModel, Boolean>() {
            @Override
            public Boolean call(SampleModel sampleModel) {
                return !sampleModel.getName().equals("");
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<SampleModel>() {
            @Override
            public void onCompleted() {
                LogUtils.d("--->onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                LogUtils.e(e);
            }

            @Override
            public void onNext(SampleModel sampleModel) {
                LogUtils.d("--->onNext");
                Glide.with(TwoActivity.this).load(sampleModel.getContent()).into(tiffanyImg);
                tiffanyText.setText(sampleModel.getName());
            }
        });
    }

    //制造数据源
    private void makeSampleModelData() {
        data = new ArrayList<>();
        data.add(new SampleModel("Tiffany one", "http://hiphotos.baidu.com/zhixin/abpic/item/4651a712c8fcc3cea97dbce49045d688d53f206c.jpg"));
        data.add(new SampleModel("Tiffany two", "http://pic.5442.com/2014/0930/06/5442.jpg"));
        data.add(new SampleModel("", "http://img5q.duitang.com/uploads/item/201410/22/20141022214043_5EEKH.thumb.224_0.jpeg"));
        data.add(new SampleModel("Tiffany four", "http://img5.duitang.com/uploads/item/201512/08/20151208163159_HGEM2.thumb.224_0.png"));
        data.add(new SampleModel("Tiffany five", "http://img4.duitang.com/uploads/item/201510/29/20151029224537_ijEKF.thumb.224_0.jpeg"));
    }

}

首先,我们在初始化的时候打了个Thread,然后再接下来的操作力再分别打出Thread,很明显除了加载操作,别的逻辑都让他在子线程里操作,为什么?最后说,先看下去!

这一部分主要实现在于setPhotoForOne这个方法

我们给被观察者传入一个ArrayList<SampleModel>对象,然后让他在新线程里做数据整合的一些行为.subscribeOn(Schedulers.newThread()),接着调用了 .map方法,在这里的Func1我传入了一个键值对。

第一个参数为传入的参数 参数类型也就是ArrayList<SampleModel>

第二个为返回的参数类型 为SampleModel

这极大的简便了我们的操作,不再是传统的传什么返回什么,让我们的代码有更好的拓展性,事件可以分的更清楚(L表达式情况下,传统的回调地狱还是蛮烦的,但是有好有坏,一个可读性好,一个代码少)

并且可以多次调用来满足我们的业务需求,像这样

.map(new Func1<SampleModel, String>() {
            @Override
            public String call(SampleModel sampleModel) {
                LogUtils.d("第二个call线程id " + Thread.currentThread().getId());
                return sampleModel.getContent();
            }
        })

当然我们的UI操作,还是要回到主线程来做,不然会有异常,但是这么做的一个好处是我们的复杂操作(异步,数据库,IO等都利用多CPU的优势来降低主线程的压力) 可以达到尽量避免卡UI的情况,重要的事情说三次 避免卡UI 避免卡UI 避免卡UI

 .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String url) {
                        LogUtils.d("第三个call线程id " + Thread.currentThread().getId());
                        LogUtils.d("--->开始加载 " + url);
                        Glide.with(TwoActivity.this).load(url).into(tiffanyImg);
                    }
                });


然后再来提提另外2个方法 filter() 和 flatMap()

 .flatMap(new Func1<ArrayList<SampleModel>, Observable<SampleModel>>() {
                    @Override
                    public Observable<SampleModel> call(ArrayList<SampleModel> sampleModels) {
                        return Observable.from(sampleModels);
                    }
                })

这里的Func1也是传入2个参数

第一个为传入的类型,第二个是返回的Observable对象

和map一样他们都可以改变类型,但是只是返回的类型不同而已,大家可以根据自己的需求来选择不同的方法。

那返回的Observable又能干吗呢?

我们可以对他进行再次的嵌套,诸如二次just,二次from等等,有很大的拓展性

接下来再来提一下 .filter()

他可以为我们做“筛选”操作,

.filter(new Func1<SampleModel, Boolean>() {

@Override

public Boolean call(SampleModel sampleModel) {

return !sampleModel.getName().equals("");

}

})

false就会被过滤掉,也就是不会被观察者所执行

看下Log就清楚了

我们name为”“的那条数据就没有走onNext方法。

Ok,为什么用RxJava

1 不用再去麻烦的扣Handler做逻辑判断

2 更好的线程处理,方便好用

3 强大的API

源码地址:https://github.com/ddwhan0123/RxAndroidDemo

有问题可以WeChat我(活人,非公众号)

友情链接:http://gank.io/post/560e15be2dca930e00da1083#toc_1

时间: 2024-08-01 20:10:24

初涉RxAndroid .map() . filter() flatMap()的相关文章

spark 教程三 spark Map filter flatMap union distinct intersection操作

RDD的创建 spark 所有的操作都围绕着弹性分布式数据集(RDD)进行,这是一个有容错机制的并可以被并行操作的元素集合,具有只读.分区.容错.高效.无需物化.可以缓存.RDD依赖等特征 RDD的创建基础RDD 1.并行集合(Parallelized Collections):接收一个已经存在的Scala集合,然后进行各种并行运算 var sc=new SparkContext(conf) var rdd=sc.parallelize(Array(2,4,9,3,5,7,8,1,6)); rd

第88讲:Scala中使用For表达式实现map、flatMap、filter

今天我们来学习一下如何使用for表达式实现map.flatMap以及filter 首先,我们来看下map.map的功能是,传入一个list,通过一个函数f,将list中的元素A变成元素B的过程.最后得到由B形成的列表.这个过程如果由for循环实现的话,如下操作: for(element <- list) yield f(element) 接下来我们看下flatMap.flatMap的功能是,传入一个list,通过一个函数f,将list中的每个元素转换成一个列表,最后返回由这些列表中的所有元素构成

Scala深入浅出实战经典《第88讲:Scala中使用For表达式实现map、flatMap、filter》笔记

简直了....晚上回来突然看到了进巨的原稿,忍不住撸了幅三爷,然后什么都没做就23点了... 第88讲:Scala中使用For表达式实现map.flatMap.filter Goal: For表达式实现map/flatMap/filter Gains: map/flatMap/filter是泛型 More: ...... ------------------------------------------------------------------------------------ 信息来

Scala中使用For表达式实现map、flatMap、filter

学习了Scala中使用For表达式实现map.flatMap.filter,可以实现广泛的应用 例子如下: Object For_Advancde { Def main(args: Array[String]) {} Def map[A,B](List: List[A], f:A=>B):List[B]= For (element <-list) yield f(element) Def flatmap[A,B](List: List[A], f:A=>B):List[B]= For (

Stream之filter、distinct、skip、map、flatMap、match、find、reduce

一.Stream之filter.distinct.skip: 1 package com.cy.java8; 2 3 import java.util.Arrays; 4 import java.util.List; 5 import java.util.stream.Collectors; 6 7 public class StreamFilter { 8 9 public static void main(String[] args) { 10 List<Integer> list = A

【Swift】Map、FlatMap、CompactMap、CompactMapValues、Filter、Reduce

Map map函数能够被数组调用,它接受一个闭包作为参数,作用于数组中的每个元素.闭包返回一个变换后的元素,接着将所有这些变换后的元素组成一个新的数组 1. 比如我们有一个这样的需求遍历一个数组中所有的元素,将每个元素自身与自身相加,最后返回一个保存相加后元素的数组(-_-原谅我这表达能力,下面用代码阐述) 如果我们不使用map函数,那么代码如下 let numbers = [1,2,3] var sumNumbers = [Int]() for var number in numbers {

spark 的一些常用函数 filter,map,flatMap,lookup ,reduce,groupByKey

定义不带参数也不带返回值的函数(def :定义函数的关键字  printz:方法名称) scala> def printz = print("scala hello") 定义带参数也带返回值的函数(这种函数在定义时也可以不带返回值的类型,scala会自动推算出.建议还是带上) scala> def minNum(x:Int,y:Int):Int = if(x>y) x else y //:Int 是该函数的返回值类型 minNum: (x: Int, y: Int)I

scala 88 for替换map,flatmap,filtermap,for,scala,flatmap

王家林亲授<DT大数据梦工厂>大数据实战视频“Scala深入浅出实战经典”视频.音频和PPT下载!第88讲:Scala中使用For表达式实现map.flatMap.filter百度云盘:http://pan.baidu.com/s/1mgtgcIG360云盘:http://yunpan.cn/cdXsbctXfDNyC 访问密码 4e30腾讯微云:http://url.cn/VjOGea本节王老师讲了for可以替换map,flatmap,和filter.def map[A,B](list:Li

Python -- lambda, map, filter

lambda f = lambda x : x * 2 f(5) map list(map(lambda x:x[0].upper()+x[1:].lower(), ['sQd', 'ZORO'])) #传入列表,首字母变大写,其余变小写 filter list(filter(lambda n: n%2 == 1, [1,2,3,4,5])) #保留奇数,舍弃偶数 list(filter(lambda s: s and s.strip(), ['S', '', None, 'b'])) #删除一