Android函数响应式编程——必学的RxJava变换操作符map、flatMap、cast、concatMap、flatMapIterable、buffer、groupBy

这篇博客详细介绍了在Android函数响应式编程中,如何使用RxJava的变换操作符,如map用于单一数据转换,flatMap用于多个数据转换并保持顺序,cast用于类型转换,concatMap确保顺序正确,flatMapIterable处理可迭代数据,以及buffer如何将数据分组。通过实例展示了这些操作符的用法和效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

gradle

//    RxJava
    compile 'io.reactivex:rxjava:1.2.0'
    compile 'io.reactivex:rxandroid:1.2.1'



变换操作符:对被观察者(Oberserver)要发射的数据进行修改,修改后再发送出去。


1.map:把你原来观察者的数据进行修改(Retrofit就是采用的这个方式,把根地址和子地址拼接)


先创建一个正常的Observable

rx.Observable observable = rx.Observable.just("qq/lol");

再写一个func:意思就是对Observable要发送的数据进行修改

final String baseUrl = "http://www.baidu.com/";

Func1<String, String> func1 = new Func1<String, String>() {
    @Override
    public String call(String s) {
        return baseUrl + s;
    }
};

修改操作:返回一个新的Obervable(因为这个方法的内部机制是重新创建了一个Observable)

rx.Observable newObservable = observable.map(func1);


观察者和订阅:(你不能订阅那个老的Observable)

Action1<String> onNextAction = new Action1<String>() {
    @Override
    public void call(String s) {
        Log.i("xbh", s);
    }
};

newObservable.subscribe(onNextAction);


输出结果:

12-09 03:51:14.906 23341-23341/? I/xbh: http://www.baidu.com/qq/lol


2.flatMap、cast:和上面的有所区别,这次是把给多个子url添加一个baseUrl。


被观察者

rx.Observable observable = rx.Observable.just("qq/chiji", "qq/feiche", "qq/xuanwu", "qq/55kai");

func:

final String baseUrl = "http://www.baidu.com/";

Func1<String, rx.Observable<?>> func1 = new Func1<String, rx.Observable<?>>() {
    @Override
    public rx.Observable<?> call(String s) {
        return rx.Observable.just(baseUrl + s);
    }
};
第二个方法可能难以理解:因为现在的数据是4个,那么实际上这个call方法是执行了4次(后来我打印了日志确认就是这样)。所以s代表的是这4个不同的数据。


修改操作:

rx.Observable newObservable = observable.flatMap(func1).cast(String.class);

输出日志:

12-09 04:17:43.811 15188-15188/com.hdu.a15058124.homework3 I/xbh: http://www.baidu.com/qq/chiji
12-09 04:17:43.811 15188-15188/com.hdu.a15058124.homework3 I/xbh: http://www.baidu.com/qq/feiche
12-09 04:17:43.811 15188-15188/com.hdu.a15058124.homework3 I/xbh: http://www.baidu.com/qq/xuanwu
12-09 04:17:43.811 15188-15188/com.hdu.a15058124.homework3 I/xbh: http://www.baidu.com/qq/55kai


3.concatMap:上面那个方法的输出可能会不是按照我们刚刚的顺序来,这个方法可以确保顺序正确。

使用:只需要把上述flatMap换成concatMap即可


4.flatMapIterable:和上面的大致相仿,只是有些地方需要修改一下。


func

Func1<String, Iterable<String>> func1 = new Func1<String, Iterable<String>>() {
    @Override
    public Iterable<String> call(String s) {
        List<String> list = new ArrayList<>();
        list.add(baseUrl + s);
        return list;
    }
};

修改:

rx.Observable newObservable = observable.flatMapIterable(func1).cast(String.class);


5.buffer:比如给定123456 buffer(2)就是让他们每两个成为1组,把每两个数处理成一个List<Integer>


被观察者:

rx.Observable observable = rx.Observable.just(1,2,3,4,5,6);

修改:现在可以看做rx.Observable<List<Integer>> newObservable = rx.Observable.just(list1,list2,list3);list1放的是12,list2放的是34,list3放的是56

rx.Observable<List<Integer>> newObservable = observable.buffer(2);

观察者:

Action1<List<Integer>> onNextAction = new Action1<List<Integer>>() {
    @Override
    public void call(List<Integer> list) {
        for (Integer i : list) {
            Log.i("xbh", i + "");
        }
        Log.i("xbh", " ");
    }
};

订阅:

newObservable.subscribe(onNextAction);

输出日志:

12-09 04:50:34.015 12938-12938/? I/xbh: 1
12-09 04:50:34.015 12938-12938/? I/xbh: 2
12-09 04:50:34.015 12938-12938/? I/xbh:  
12-09 04:50:34.015 12938-12938/? I/xbh: 3
12-09 04:50:34.015 12938-12938/? I/xbh: 4
12-09 04:50:34.015 12938-12938/? I/xbh:  
12-09 04:50:34.015 12938-12938/? I/xbh: 5
12-09 04:50:34.015 12938-12938/? I/xbh: 6
12-09 04:50:34.015 12938-12938/? I/xbh:  


6.groupBy

简单来说。

比如:

Book b1 = new Book("Android群英传之神兵利器","A");
Book b2 = new Book("Android进阶之光","SSS");
Book b3 = new Book("Android高级进阶","SS");
Book b4 = new Book("Android群英传","A");
Book b5 = new Book("源码","SSSS");
Book b6 = new Book("第一行代码(第二版)","SS");

你给他一个标准,比如,按后面的英文字母排序,就会这样输出:

12-09 05:23:02.993 10082-10082/com.hdu.a15058124.homework3 I/xbh: 书名:Android群英传之神兵利器 书的质量:A
12-09 05:23:02.993 10082-10082/com.hdu.a15058124.homework3 I/xbh: 书名:Android群英传 书的质量:A
12-09 05:23:02.994 10082-10082/com.hdu.a15058124.homework3 I/xbh: 书名:Android进阶之光 书的质量:SSS
12-09 05:23:02.994 10082-10082/com.hdu.a15058124.homework3 I/xbh: 书名:Android高级进阶 书的质量:SS
12-09 05:23:02.994 10082-10082/com.hdu.a15058124.homework3 I/xbh: 书名:第一行代码(第二版) 书的质量:SS
12-09 05:23:02.994 10082-10082/com.hdu.a15058124.homework3 I/xbh: 书名:源码 书的质量:SSSS


被观察者

rx.Observable observable = rx.Observable.just(b1,b2,b3,b4,b5,b6);

func:也是排序的标准

Func1<Book,String> func1 = new Func1<Book, String>() {
    @Override
    public String call(Book book) {
        return book.getBookQuality();
    }
};

排序规则:

rx.Observable<GroupedObservable<String, Book>> GroupedObservable =
        observable.groupBy(func1);

根据排序规则返回的新的被观察者:

rx.Observable<Book> newObservable = rx.Observable.concat(GroupedObservable);

观察者

Action1<Book> onNextAction = new Action1<Book>() {
    @Override
    public void call(Book book) {
        Log.i("xbh", "书名:" + book.getBookName() +
                " 书的质量:" + book.getBookQuality());
    }
};

订阅

newObservable.subscribe(onNextAction);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值